IOC容器的设计(二) — BeanFactory 的设计原理
IOC容器的设计(二) — BeanFactory 的设计原理
BeanFactory提供了容器的基本规范,Spring 提供一系列以BeanFactory为基础的容器提供给开发人员使用,下面以XmlBeanfactory为例:
XmlBeanFactory类继承关系
我们可以清楚的看到XmlBeanFactory作为IoC底层的实现,只继承了DefaultListableBeanFactory
,而DefaultListableBeanFactory
是包含基本IoC容器所具有的所有功能,XmlBeanFactory
在继承DefaultListableBeanFactory
的基础上,增加了新的功能。XmlBeanFactory
主要是需要解析XML定义的信息,而处理XML信息则是交给XmlBeanDefinitionReader
来进行处理。 下面我们看一下XmlBeanFactory
的源码:
public class XmlBeanFactory extends DefaultListableBeanFactory {
//创建reader对象
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
/**
* Create a new XmlBeanFactory with the given resource,
* which must be parsable using DOM.
* @param resource XML resource to load bean definitions from
* @throws BeansException in case of loading or parsing errors
*/
public XmlBeanFactory(Resource resource) throws BeansException {
this(resource, null);
}
/**
* 实例XmlBeanFactory对象,传入资源以及父类BeanFactory,解析并加载resource对象
* @param resource XML resource to load bean definitions from
* @param parentBeanFactory parent bean factory
* @throws BeansException in case of loading or parsing errors
*/
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
super(parentBeanFactory);
this.reader.loadBeanDefinitions(resource);
}
}
构造XmlBeanFactory容器时,需要指定BeanDefination的信息来源,这个时候需要的是Resource,Resource是Spring 用来封装I/O操作的类,这个时候需要ClassPathResource来讲XML信息转化为Resource。这样方便IOC容器定位BeanDefiantion信息来完成Bean的初始化以及Bean的依赖注入过程。拿到Resource对象后,需要使用解析Xml的reader来进行读取,即调用loadBeanDefinitions(),loadBeanDefinitions是IOC容器的初始化的核心部分。
下面我们使用XmlBeanFactory作为IOC容器来实现对bean.xml的解析。
bean.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="demo1User" class="com.wangteng.dto.Person"/>
</beans>
//1. 创建将XML转换为Resource的对象
ClassPathResource resource = new ClassPathResource("bean.xml");
//2. 创建IOC容器,并通过构造方法解析resource
XmlBeanFactory factory = new XmlBeanFactory(resource);
//3. 从容器中拿到实例对象
Person bean =factory.getBean(Person.class,"zhangsan","12");
System.out.println(bean);
结果:
Person(userGid=zhangsan, name=12)
参考XMLBeanFactory的实现,尝试用编程的方式使用DefaultListableBeanFactory。
//1. 创建将XML转换为Resource的对象
ClassPathResource resource = new ClassPathResource("bean.xml");
//2. 创建默认IOC容器
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
//3. 创建XmlBeanDefinitionReader对resource进行加载
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
//4. 将resource解析成BeanDefination对象
reader.loadBeanDefinitions(resource);
//5. 从容器中拿到实例对象
Person bean =factory.getBean(Person.class,"zhangsan","12");
System.out.println(bean);