IOC容器的设计(二) — BeanFactory 的设计原理

IOC容器的设计(二) — BeanFactory 的设计原理

BeanFactory提供了容器的基本规范,Spring 提供一系列以BeanFactory为基础的容器提供给开发人员使用,下面以XmlBeanfactory为例:

XmlBeanFactory类继承关系

IOC容器的设计(二) — BeanFactory 的设计原理

我们可以清楚的看到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);