注册BeanDefinitions
通过XmlBeanDefinitionReader.doLoadDocument()
获取了XML Documents
对象后,会使用该Document对象和Resource资源对象通过XmlBeanDefinitionReader.registerBeanDefinitions()
开始注册BeanDefinitions
。
1 2 3 4 5 6 7 8 9 10 11
| public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); int countBefore = getRegistry().getBeanDefinitionCount(); documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); return getRegistry().getBeanDefinitionCount() - countBefore; }
|
createBeanDefinitionDocumentReader()
方法
createBeanDefinitionDocumentReader()
实例化BeanDefinitionDocumentReader
对象,用来从XML文件中读取bean定义,默认实例化指定的documentReaderClass
,即DefaultBeanDefinitionDocumentReader.class
。
1 2 3 4 5
| private Class<? extends BeanDefinitionDocumentReader> documentReaderClass = DefaultBeanDefinitionDocumentReader.class; protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() { return BeanUtils.instantiateClass(this.documentReaderClass); }
|
registerBeanDefinitions()
方法
BeanDefinitionDocumentReader.registerBeanDefinitions(Document doc, XmlReaderContext readerContext)
方法,注册 BeanDefinition ,在接口 BeanDefinitionDocumentReader 中定义。
机翻方法注释:从给定的DOM文档中读取bean定义,并在给定的阅读器上下文中向注册表注册它们。
1 2 3 4
| public interface BeanDefinitionDocumentReader { void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) throws BeanDefinitionStoreException;
}
|
DefaultBeanDefinitionDocumentReader
该类是BeanDefinitionDocumentReader
的实现类,且是唯一一个。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| @Override public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) { this.readerContext = readerContext; doRegisterBeanDefinitions(doc.getDocumentElement()); }
protected void doRegisterBeanDefinitions(Element root) { BeanDefinitionParserDelegate parent = this.delegate; this.delegate = createDelegate(getReaderContext(), root, parent); if (this.delegate.isDefaultNamespace(root)) { String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE); if (StringUtils.hasText(profileSpec)) { String[] specifiedProfiles = StringUtils.tokenizeToStringArray( profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS); if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) { if (logger.isDebugEnabled()) { logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + getReaderContext().getResource()); } return; } } } preProcessXml(root); parseBeanDefinitions(root, this.delegate); postProcessXml(root); this.delegate = parent; }
|
createDelegate()
方法
BeanDefinitionParserDelegate
负责解析BeanDifinition
对象,定义了解析XML Element的各种方法,如下获取BeanDefinitionParserDelegate
:
1 2 3 4 5 6 7 8
| createDelegateprotected BeanDefinitionParserDelegate createDelegate( XmlReaderContext readerContext, Element root, @Nullable BeanDefinitionParserDelegate parentDelegate) { BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext); delegate.initDefaults(root, parentDelegate); return delegate; }
|
parseBeanDefinitions()
方法
对给定的Element
进行解析:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { if (delegate.isDefaultNamespace(root)) { NodeList nl = root.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (node instanceof Element) { Element ele = (Element) node; if (delegate.isDefaultNamespace(ele)) { parseDefaultElement(ele, delegate); } else { delegate.parseCustomElement(ele); } } } } else { delegate.parseCustomElement(root); } }
|
- Spring有两种Bean声明方式:
- 配置文件式声明,例:
<bean id="lizi" class="com.jievhaha.lizi"/>
,使用<1>处解析
- 自定义注解方式:
<tx:anntation-driven>
,执行<2>处解析
子节点或者根节点使用默认命名空间,执行默认解析,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); } else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { processAliasRegistration(ele); } else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { processBeanDefinition(ele, delegate); } else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { doRegisterBeanDefinitions(ele); } }
|
createReaderContext()
方法
文章开头,注册BeanDefinition对象时需要上送XmlReaderContext
对象:
1 2 3 4 5 6 7 8
| private ProblemReporter problemReporter = new FailFastProblemReporter(); private ReaderEventListener eventListener = new EmptyReaderEventListener(); private SourceExtractor sourceExtractor = new NullSourceExtractor();
public XmlReaderContext createReaderContext(Resource resource) { return new XmlReaderContext(resource, this.problemReporter, this.eventListener, this.sourceExtractor, this, getNamespaceHandlerResolver()); }
|
小结
XmlBeanDefinitionReader.doLoadBeanDefinitions
解析过程时序图:
红框是解析过程。