1. 获取BeanFactory
在SpringIOC容器创建的主流程中,第二步就是获取一个BeanFactory对象,详情可见如下方法 org.springframework.context.support.AbstractApplicationContext#refresh,入口如下:
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
进入**obtainFreshBeanFactory()**方法,看到如下内容:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 1. 初始化BeanFactory对象
refreshBeanFactory();
// 2. 返回BeanFactory对象
return getBeanFactory();
}
第一步: 初始化BeanFactory对象: **refreshBeanFactory()**方法
org.springframework.context.support.AbstractRefreshableApplicationContext#refreshBeanFactory
@Override
protected final void refreshBeanFactory() throws BeansException {
//判断是否已有beanFactory
if (hasBeanFactory()) {
//销毁beans
destroyBeans();
//关闭beanFactory
closeBeanFactory();
}
try {
//实例化DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
//设置序列化ID
beanFactory.setSerializationId(getId());
//自定义bean工厂的一些属性(是否覆盖,是否循环依赖)
customizeBeanFactory(beanFactory);
//加载应用中的BeanDefinitions
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
//赋值当前bean工厂
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
创建BeanFactory,很显然进到createBeanFactory方法中,
protected DefaultListableBeanFactory createBeanFactory() {
return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
通过上图可以清晰得看到,BeanFactory是一个顶级的接口,那么在实例化过程中,默认的实现就是DefaultListableBeanFactory对象。
第二步:返回BeanFactory对象:getBeanFactory()方法
org.springframework.context.support.AbstractRefreshableApplicationContext#getBeanFactory
@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
synchronized (this.beanFactoryMonitor) {
if (this.beanFactory == null) {
throw new IllegalStateException("BeanFactory not initialized or already closed - " +
"call 'refresh' before accessing beans via the ApplicationContext");
}
return this.beanFactory;
}
}
从上述代码可看出,第二步也就是返回了第一步初始化的BeanFactory的实例化对象。
时序图:
2. BeanDefinition加载解析及注册子流程
2.1 关键步骤
1.Resource定位: 指对BeanDefinition资源的定位过程,也就是找到定义Java Bean的XML文件,并将其中的定义的Bean封装成BeanDefinition对象。
2.BeanDefinition载入: 将XML中定义的Bean封装成的BeanDefinition对象注册到Spring IOC容器中,方便注入和调用。
2.2 Resource定位
step-1. 流程入口
⼦流程⼊⼝在 AbstractRefreshableApplicationContext#refreshBeanFactory
step-2. 加载Resource文件和解析
依次调⽤多个类的 loadBeanDefinitions ⽅法 —> AbstractXmlApplicationContext —>
AbstractBeanDefinitionReader —> XmlBeanDefinitionReader ⼀直执⾏到
XmlBeanDefinitionReader 的 doLoadBeanDefinitions ⽅法
我们重点观察XmlBeanDefinitionReader 类的 registerBeanDefinitions ⽅法,期间产⽣了多次重载调⽤,我们定位到最后⼀个
关注1的createReaderContext方法:
此处Spring首先完成了NamespaceHandlerResolver的初始化。
关注2的documentReader.registerBeanDefinitions方法,调用了DefaultBeanDefinitionDocumentReader#registerBeanDefinitions ⽅法
进入doRegisterBeanDefinitions方法:
进入parseBeanDefinitions方法:
进入到parseDefaultElement方法:
进入processBeanDefinition方法:
⾄此,Resource文件定位和解析过程结束,我们发现,所谓的注册就是把封装的 XML 中定义的 Bean信息解析成了一个BeanDefinitionsHolder对象。
2.3 BeanDefinition载入
在上一节中已经将XML文件中定义的Bean封装成了BeanDefinitionsHolder对象,接下来就是将BeanDefinition注册到IOC容器中,主要调用的就是:
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#processBeanDefinition方法:
进入到BeanDefinitionReaderUtils.registerBeanDefinition方法中,
进入registry.registerBeanDefinition方法中,就进入到了org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition方法,
⾄此,注册流程结束,我们发现,所谓的注册就是把封装的 XML 中定义的 Bean信息封装为BeanDefinition 对象之后放⼊⼀个Map中。