向容器中注册 BeanDefinition
这部分从 DefaultBeanDefinitionDocumentReader 中的processBeanDefinition
方法说起:
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
在解析完成之后,负责将 BeanDefinition 注册到容器中的是这样代码:
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
传入方法的参数,一个是之前解析道的 BeanDefinitionHolder,另一个其实就是我们最初创建的 BeanFactory(这里为什么是最初创建的 BeanFactory ?分析如下:)。
这里的
registry
就是我们起初创建的 BeanFacoty,之前涉及到的流程已经很多了,这里再捋一下起初创建的 BeanFacoty 是怎么到这儿的。
- 在
AbstractApplicationContext
的refresh
方法中,调用了obtainFreshBeanFactory
方法,其中的refreshBeanFactory
方法通过createBeanFactory
方法创建了一个DefaultListableBeanFactory
,并赋值给了beanFactory
成员变量。- 在解析 XML 文件之前,
AbstractXmlApplicationContext
的loadBeanDefinitions
方法中,创建 XmlBeanDefinitionReader 的时候,通过构造方法,将beanFactory
赋值给了其registry
成员变量,这一步通过其父类 AbstractBeanDefinitionReader 的构造方法完成。- 在 XmlBeanDefinitionReader 的
registerBeanDefinitions
方法中,通过createBeanDefinitionDocumentReader
方法创建了 DefaultBeanDefinitionDocumentReader 类型的变量documentReader
,并在调用documentReader
的registerBeanDefinitions
方法时,通过createReaderContext
创建了一个 XmlReaderContext 作为方法的参数传递给了documentReader
并赋值给了其readerContext
成员变量。- 上一步中,
createReaderContext
方法中,将当前对象也就是 XmlBeanDefinitionReader 对象作为参数传入并赋值给了reader
成员变量,而 DefaultBeanDefinitionDocumentReader 调用getReaderContext().getRegistry()
方法的时候,getReaderContext
获取到的是之前创建的