准备好了环境之后,接下来要做的事情是初始化BeanFactory,并进行XML文件读取。总的一句话就是加载BeanFactory。那么Spring是如何实现这个功能呢?接下来笔者就要分析。在分析之前,我们先看一张时序图。(相关资源可到这里下载:http://pan.baidu.com/s/1sjSo9a9)
1. AbstractRefreshableApplicationContext
跟踪程序的执行,代码将进入AbstractRefreshableApplicationContext类的refreshBeanFactory的函数。在这里主要做的事情就是:
1) 创建DefaultListableBeanFactory
2) 指定序列化ID
3) 定制BeanFactory
4) 加载BeanDefinition
5) 使用全局变量记录BeanFactory类实例
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//创建DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
//为了序列化指定id,如果需要的话,让BeanFactory从id反序列化到BeanFactory对象
beanFactory.setSerializationId(getId());
//定制beanFactory,设置相关属性,包括是否允许覆盖名称的不同定义的对象及循环依赖以及
//设置@Autowired和@Qualifier,注解解析 器QualifierAnnotationAutowireCandidateResolver
<strong>customizeBeanFactory(beanFactory)</strong>;
//初始化DodumentReader,并进行XML文件读取及解析
<strong>loadBeanDefinitions(beanFactory)</strong>;
synchronized (this.beanFactoryMonitor) {
<strong>this.beanFactory = beanFactory</strong>;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
在这个函数中,我们先来看第一个关键的函数customizeBeanFactory。这里开如了对BeanFactory的扩展,在基本容器的基础上,增加了是否允许覆盖,是否允许扩展的设置,并提供了注解@Qualifier和@Autowired的支持。
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
//如果属性allowBeanDefinitionOverriding不为空,设置给beanFactory对象相应属性
//此属性含义:是否允许覆盖同名称的不同定义对象
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
//如果属性allowCircularReferences不为空,设置给beanFactory对象相应属性
//此属性的含义:是否允许bean之间存循环依赖
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
//用于@Qualifier和@Autowired
beanFactory.setAutowireCandidateResolver(<strong>new QualifierAnnotationAutowireCandidateResolver()</strong>);
}
2. QualifierAnnotationAutowireCandidateResolver
在上面的定制BeanFactory的函数中,我们还要注意最后的一个方法,那就是去实例化QualifierAnnotationAutowireCandidateResolver,其实就是去实现这个类的getSuggestValue()的函数。
public Object getSuggestedValue(DependencyDescriptor descriptor) {
Object value = findValue(descriptor.getAnnotations());
if (value == null) {
MethodParameter methodParam = descriptor.getMethodParameter();
if (methodParam != null) {
value = findValue(methodParam.getMethodAnnotations());
}
}
return value;
}
3. AbstractXmlApplicationContext
接下来,我们还是要回到refreshBeanFactory()的函数中,还有一个重要的方法,那就是loadBeanDefinitions().这个函数其实就是在类AbstractXmlApplicationContext里的,实现的具体过程如下。
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
//为指定beanFactory创建XmlBeanDefinitionReader
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// Configure the bean definition reader with this context's
// resource loading environment.
//对beanDefinitionReader进行环境变量设置
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
//对BeanDefinitionReader进行设置,可以覆盖
initBeanDefinitionReader(beanDefinitionReader);
<strong>loadBeanDefinitions(beanDefinitionReader)</strong>;
}
而最后一个loadBeanDefinitions的方法就是在这个类中的,所以它的实现如下。
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
4.总结
这一节主要分析的是初始化BeanFactory,并进行XML文件读取。这里首先就是要定制beanFactory,设置相关属性,包括是否允许覆盖同名称的不同定义的对象以及循环依赖,及主,设置@Autowired和@Qualifier注解解析器QualifierAnnotationAutowireCandidateResolver 。其次就是初始化DodumentReader,并进行XML文件读取及解析。