IOC原理简述:所谓IOC,对于Spring框架来说,就是由spring负责控制对象的生命周期和对象间的关系。
说白了也就是我们在创建对象时,由原先的程序员创建对象反转为由容器控制这些操作,在bean工厂中创建对象,程序员只需要在使用某个对象时直接从容器中获取。
1、配置需要容器进行管理的bean文件。
bean文件中配置id和class。容器中根据配置中的id获取到类的全限定名(com.xoyar.dao.Impl.UserDaoImpl),利用反射机制创建对象。
反射:Class.forName("全限定名").newInstance()
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="u" class="com.xoyar.dao.Impl.UserDaoImpl"></bean>
</beans>
2、这里到了IOC的核心部分。我们首先创建BeanFactory接口,这里包含一个getBean的方法,用来获取bean。
3、创建BeanFactory的实现类ClassPathXmlApplication。在此类中进行具体的实现。
3.1、创建容器,这里用到Map。
3.2、为了在加载容器时就初始化bean,这里需要在ClassPathXmlApplication的构造方法中完成解析xml和创建对象的工作。
3.2.1、构造方法中的具体实现见代码注释。
ps:此处解析xml用到了jdom-1.0.jar。
/**
* Bean工厂的实现类,在此类中利用反射创建所有需要的对象并存放在容器中。
* 不需要手动创建对象
* 需要对象时可在bean工厂直接获取getBean()
*/
public class ClassPathXmlApplication implements BeanFactory {
/**
* 建立容器
*/
Map<String,Object> beans = new HashMap<>();
/**
* 通过反射机制根据类的全限定名,创建类对象
* 在加载容器时就初始化xml文件中配置的所有对象
*/
public ClassPathXmlApplication() throws Exception {
//使用jdom包中的SAXBuilder解析xml文件
SAXBuilder saxBuilder = new SAXBuilder();
//将beans.xml加载到Document中
Document document = saxBuilder.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml"));
//先获取根元素,再用根元素获取子元素<bean/>
Element rootElement = document.getRootElement();
List list = rootElement.getChildren("bean");
//获取每个元素的id和class
for (int i=0;i<list.size();i++){
Element element = (Element) list.get(i);
String id = element.getAttributeValue("id");
String clazz = element.getAttributeValue("class");
System.out.println("id = "+id+" class = "+clazz);
//通过反射创建对象
Object o = Class.forName(clazz).newInstance();
//将对象放入容器中
beans.put(id,o);
}
}
@Override
public Object getBean(String id) {
return beans.get(id);
}
}
至此,就可以通过实例化ClassPathXmlApplication调用getBean方法就可以从外部直接获取对象了。