BeanDefinition加载注册子流程
- 时序图
- 时序图1
- step0、new ClassPathXmlApplicationContext
- step1、ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String)
- step2、ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String[], boolean, org.springframework.context.ApplicationContext)
- step3、AbstractApplicationContext#refresh
- step4、AbstractApplicationContext#obtainFreshBeanFactory
- step5、AbstractRefreshableApplicationContext#refreshBeanFactory
- step6、AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.support.DefaultListableBeanFactory)
- step7、AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.xml.XmlBeanDefinitionReader)
- 时序图2
- step1、AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String...)
- step2、AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String)
- step3、AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String, java.util.Set<org.springframework.core.io.Resource>)
- step4、AbstractBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource...)
- step5、XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource)
- step6、XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.support.EncodedResource)
- step7、XmlBeanDefinitionReader#doLoadBeanDefinitions
- step8、XmlBeanDefinitionReader#registerBeanDefinitions
- step9、DefaultBeanDefinitionDocumentReader#registerBeanDefinitions
- step10、DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions
- step11、DefaultBeanDefinitionDocumentReader#parseBeanDefinitions
- step12、DefaultBeanDefinitionDocumentReader#parseDefaultElement
- step13、DefaultBeanDefinitionDocumentReader#processBeanDefinition
- step14、BeanDefinitionReaderUtils#registerBeanDefinition
- step15、DefaultListableBeanFactory#registerBeanDefinition
时序图
先上时序图,
这两张时序图加起来是完整的BeanDefinition加载注册子流程。
时序图1
step0、new ClassPathXmlApplicationContext
step1、ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String)
step2、ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String[], boolean, org.springframework.context.ApplicationContext)
step3、AbstractApplicationContext#refresh
step4、AbstractApplicationContext#obtainFreshBeanFactory
step5、AbstractRefreshableApplicationContext#refreshBeanFactory
开始加载应用中的BeanDefinitions
step6、AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.support.DefaultListableBeanFactory)
创建xmlBeanDefinition读取器并设置上下文环境、加载BeanDefinitions
/**
* Loads the bean definitions via an XmlBeanDefinitionReader.
* @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
* @see #initBeanDefinitionReader
* @see #loadBeanDefinitions
*/
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 为给定的BeanFactory创建一个xmlBeanDefinition读取器
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// 给xmlBeanDefinition读取器设置上下文环境
// Configure the bean definition reader with this context's
// resource loading environment.
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.
initBeanDefinitionReader(beanDefinitionReader);
// 加载BeanDefinitions
loadBeanDefinitions(beanDefinitionReader);
}
step7、AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.xml.XmlBeanDefinitionReader)
从xml文件加载BeanDefinition的信息
时序图2
step1、AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String…)
若有多个配置文件,for循环加载
step2、AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String)
step3、AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String, java.util.Set<org.springframework.core.io.Resource>)
获取资源加载器、将xml配置文件转为Resource资源对象、从Resource加载BeanDefinitions
step4、AbstractBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource…)
若有多个Resource对象,for循环加载
step5、XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource)
step6、XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.support.EncodedResource)
从Resource对象中获取inputStream流
step7、XmlBeanDefinitionReader#doLoadBeanDefinitions
将inputStream流解析为Document对象、解析Document对象封装BeanDefinition对象并注册
/**
* Actually load bean definitions from the specified XML file.
* @param inputSource the SAX InputSource to read from
* @param resource the resource descriptor for the XML file
* @return the number of bean definitions found
* @throws BeanDefinitionStoreException in case of loading or parsing errors
* @see #doLoadDocument
* @see #registerBeanDefinitions
*/
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
// 读取xml文件,将xml中的bean定义信息保存到Document对象
Document doc = doLoadDocument(inputSource, resource);
// 解析Document对象,封装BeanDefinition并注册
int count = registerBeanDefinitions(doc, resource);
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + count + " bean definitions from " + resource);
}
return count;
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (SAXParseException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
}
catch (SAXException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"XML document from " + resource + " is invalid", ex);
}
catch (ParserConfigurationException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Parser configuration exception parsing XML from " + resource, ex);
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"IOException parsing XML document from " + resource, ex);
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Unexpected exception parsing XML document from " + resource, ex);
}
}
至此,bean定义信息读取完成,
开始注册BeanDefinition。
step8、XmlBeanDefinitionReader#registerBeanDefinitions
创建BeanDefinitionDocumentReader、注册BeanDefinitions
step9、DefaultBeanDefinitionDocumentReader#registerBeanDefinitions
step10、DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions
解析Document
step11、DefaultBeanDefinitionDocumentReader#parseBeanDefinitions
解析默认标签元素、解析自定义标签元素
step12、DefaultBeanDefinitionDocumentReader#parseDefaultElement
解析</bean/>标签
step13、DefaultBeanDefinitionDocumentReader#processBeanDefinition
封装BeanDefinition
/**
* Process the given bean element, parsing the bean definition
* and registering it with the registry.
*/
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 解析bean元素为BeanDefinitionHolder
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// 完成BeanDefinition的注册
// 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));
}
}
step14、BeanDefinitionReaderUtils#registerBeanDefinition
注册BeanDefinition
step15、DefaultListableBeanFactory#registerBeanDefinition
完成注册:this.beanDefinitionMap.put(beanName, beanDefinition);
到这儿,
完成了BeanDefinition的注册。