南阳网站建设价格/镇江网站制作公司
Spring IoC所解决的问题
Spring IoC(Inversion of Control),即控制反转,也叫依赖注入DI(Dependency Injection)是将程序的控制权交给了Spring容器,从而达到控制的反转。
- IoC降低了程序之间的耦合度。在不使用Spring框架的前提下,我们必须以创建对象的方式对两个类进行强耦合,这样,会导致我们程序的健壮性太低。如果我们程序所依赖的类出现问题,那么程序就有可能无法进行编译。而把对象创建的权利交给Spring,降低了程序之间的耦合度。
- 程序员不需要考虑对象的创建管理,而更加专注于业务逻辑。
实现步骤
Spring提供了两种IoC容器:ApplicationContext和BeanFactory。这篇博客简单的写一个简单的Bean工厂。步骤如下:
- 读取xml文件,解析节点,得到类名和属性名
- 利用反射和类加载创建该类的实例并设置其属性值
- 创建set方法利用set方法进行注入
程序代码
由于我们需要对xml文件进行解析,所以这里要引入Dom4j.jar。
- 最重要的一点,编写自定义的配置文件。这里仿照Spring的配置文件。
<?xml version="1.0" encoding="UTF-8"?>
<beans><bean id="studentDao" class="com.spring.dao.impl.StudentDao"><property name="str" value="我是学生"></property></bean><bean id="teacherDao" class="com.spring.dao.impl.TeacherDao"><property name="str" value="我是老师"></property></bean></beans>
- 实现IoC的核心代码。
package com.spring.core;import java.io.File;
import java.lang.reflect.Field;
import java.util.List;import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;public class BeanFactory {private Document document;String contextConfigLocation = "src/spring.xml";public BeanFactory() {File file = new File(contextConfigLocation);SAXReader reader = new SAXReader();try {document = reader.read(file);} catch (DocumentException e) {e.printStackTrace();}}public Object getBean(String beanName) {Element root = document.getRootElement();List<Element> elements = root.elements();String beanLocation = null;String beanPropertyName = null;String beanPropertyVal = null;for(Element e : elements) {if(e.attributeValue("id").equals(beanName)) {beanLocation = e.attributeValue("class");List<Element> propertyElements = e.elements();for(Element pE : propertyElements) {beanPropertyName = pE.attributeValue("name");beanPropertyVal = pE.attributeValue("value");}}}try {Class<?> clazz = Class.forName(beanLocation);Object obj = clazz.newInstance();Field field = clazz.getDeclaredField(beanPropertyName);field.setAccessible(true);field.set(obj, beanPropertyVal);return obj;} catch (ClassNotFoundException e1) {System.out.println(beanLocation + "类未找到");} catch (InstantiationException e1) {e1.printStackTrace();} catch (IllegalAccessException e1) {e1.printStackTrace();} catch (IllegalArgumentException e1) {e1.printStackTrace();} catch (NoSuchFieldException e1) {e1.printStackTrace();} catch (SecurityException e1) {e1.printStackTrace();}return null;}}
- DAO层实现
//IuserDao.java
package com.spring.dao;public interface IUserDao {public void print();}//StudentDao.java
package com.spring.dao.impl;import com.spring.dao.IUserDao;public class StudentDao implements IUserDao{String str;@Overridepublic void print() {System.out.println(str);}}//TeacherDao.java
package com.spring.dao.impl;import com.spring.dao.IUserDao;public class TeacherDao implements IUserDao{String str;@Overridepublic void print() {System.out.println(str);}}
- Service层实现
package com.spring.service;import com.spring.dao.IUserDao;public class UserService {private IUserDao userDao;//我们要使用set方法手动注入public void setUserDao(IUserDao userDao) {this.userDao = userDao;}public void print() {System.out.println("我是service层方法");userDao.print();}}
- Controller层实现。
package com.spring.controller;import com.spring.core.BeanFactory;
import com.spring.dao.impl.TeacherDao;
import com.spring.service.UserService;public class TestController {public static void main(String[] args) {BeanFactory beanFactory = new BeanFactory();UserService userService = new UserService();//这里是我们程序运行时需要更改的地方userService.setUserDao((IUserDao)beanFactory.getBean("teacherDao"));userService.print();}}
程序测试
我们只需改变其所注入的Bean的名称。