之前的文章,我们了解了Spring中将配置文件封装为Resource类型的实例方法后,我们就可以继续探寻XmlBeanFactory的初始化过程了。
XmlBeanFactory初始化提供了两个构造函数:
public XmlBeanFactory(Resource resource) throws BeansException {
this(resource, null);
}
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
super(parentBeanFactory);
this.reader.loadBeanDefinitions(resource);
}
上面代码中,this.reader.loadBeanDefinitions(resource); 才是资源加载的真正实现,下面时序图中,XmlBeanDefinitionReader加载数据就是在这里完成的,这个时序图,之前文章也有。
在 XmlBeanDefinitionReader加载数据之前,还有一个调用父类构造函数初始化的一个过程:super(parentBeanFactory);
跟踪代码可以看到,最终调用的是AbstractAutowireCapableBeanFactory:
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
public DefaultListableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
super(parentBeanFactory);
}
}
// 继续往上跟踪
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
public AbstractAutowireCapableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
this();
setParentBeanFactory(parentBeanFactory);
}
public AbstractAutowireCapableBeanFactory() {
super();
ignoreDependencyInterface(BeanNameAware.class);
ignoreDependencyInterface(BeanFactoryAware.class);
ignoreDependencyInterface(BeanClassLoaderAware.class);
}
}
ignoreDependencyInterface: 主要功能是忽略给定接口的自动装配功能。这样做的目的是什么?
示例说明:
当A类中有属性B类的实例b、那么Spring在获取A的Bean的时候,如果属性b还未初始化,那么Spring就会自动初始化B类,但是某些情况下,B类不会初始化,比如B类实现了BeanNameAware接口。
Spring中的介绍是:自动装配时忽略给定的依赖接口,典型的应用是通过其他方式解析Application上下文注册依赖,类似于BeanFactory通过BeanFactoryAware进行注入,或者ApplicationContext通过ApplicationContextAware进行注入。
这块多说一点,Spring创建的Bean是无状态的,所以它不知道容器(BeanFactory或者ApplicationContext)的任何信息,目的为了Bean与Spring容器解耦,如果我们需要知道一个额外的信息,我们就需要实现一些特定的接口,例如:BeanNameAware、BeanfactoryAware、BeanClassLoaderAware。因此Spring在正常初始化的时候,会忽略这些实现这些接口的类。
后期在spring容器初始化过程说明的时候,会有更深的理解。