beanFactory 是spring IoC中一个最基本的容器,位于继承图最顶端的一个接口。spring IoC容器的接口/类设计图如下所示(注:该图只包含部分接口或子类):
图 1.1(图片来源于http://www.pinhuba.com/spring/101250.htm)
作为一个最古老的祖先接口,beanFactory接口定义了一个容器应该具备的最基本的功能规范。举个现实生活中的例子,如果把容器比作一个水桶,那么beanFactory就定义了水桶所具备的最基本功能,比如说,可以装水、有个提手。为了满足不同场合的需求,在满足了最基本功能之后,还可以添加更复杂的功能,比如说抗高温、耐磨、轻便等。同理,在spring IoC容器中,子接口或子类继承祖先接口beanFactory之后,可以添加新新的功能。比如说HierarchicalBeanFactory添加了getParentBeanFactory 和 containsLocalBean两个方法。水桶有各种各样的种类,比如说塑料水桶、铝制水桶,同样spring 容器中有基于XML的容器、有基于注解的configurable容器。但是不管什么水桶,都要有一个最基本的功能:装水。对于任何一个spring 具体容器,它都需要满足beanFactory这个接口的定义。那么beanFactory定义了哪些功能呢?如下图所示:
图 1.2
唯一的一个字段 FACTORY_BEAN_PREFIX是用来区分factory bean 和factory 产生的bean。在spring中,所有的bean都是由factory产生和管理的,factory本身也是一个bean,所以这个字段就是用来区分被factory管理的普通 bean和factory bean的。这个字段的定义为:
String FACTORY_BEAN_PREFIX = "&";
通过“&”可以得到factory bean。比如说 myJndiObject 是一个普通bean,那么 &myJndiObject 返回一个factory bean。
beanFactory有很多间接子类,这里以XmlBeanFactory为例,简单分析一下。它的类继承图如图1.1红色虚线框所示。DefaultListableBeanFactory是一个功能比较完整的容器,XmlBeanFactory在继承DefaultListableBeanFactory之后,增加了一个可以读取以XML文件的方法,XML文件包含了bean的定义。其代码实现如下:
public class XmlBeanFactory extends DefaultListableBeanFactory { 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); } /** * Create a new XmlBeanFactory with the given input stream, * which must be parsable using DOM. * @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); } }
reader字段会读取bean的定义。参考XmlBeanFactory的实现,我们可以在程序中直接使用DefaultListableBeanFactory,实现和XmlBeanFactory类似的功能。
ClassPathResource resource = new ClassPathResource("bean.xml");
DefaultListableBeanFactory factory = new DefaultListableFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(resource);
这段代码实现了如下功能:
- 创建配置文件的抽象资源,这个抽象文件包含了BeanDefinition的定义;
- 创建一个BeanFactory;
- 创建一个载入BeanDefinition的读取器。使用XmlBeanDefinitionReader来读取XML文件形式的BeanDefinition;
- 从定义好的资源位置读入配置信息。读取之后,由其它容器解析、注册。