前面跟踪了Spring框架如何解析xml模式配置的bean解析(参见“一起学SF框架系列5.7-模块Beans-BeanDefinition解析”),本文主要解析注解bean(详见“一起学SF框架系列5.2-模块Beans-bean的元数据配置”)是如何被Spring框架解析的。
注解配置
注解bean的配置如下:
<!-- 配置注解模式 -->
<context:annotation-config/>
<!-- 注解模式:配置bean扫描路径 -->
<context:component-scan base-package="com.learnsf.main,com.learnsf.service,com.learnsf.demo"/>
解析入口
注解解析起点在DefaultBeanDefinitionDocumentReader.parseBeanDefinitions,如下图:
其中xml解析是方法parseDefaultElement(ele, delegate)。
入口的前面流程参见“一起学SF框架系列5.7-模块Beans-BeanDefinition解析”
解析过程
注:NamespaceHandlerSupport 根据不同 Namespace选择不同的解析器。
代码跟踪
BeanDefinitionParserDelegate.parseCustomElement(Element ele)
解析非默认命名空间定义的元素。
//过渡类
@Nullable
public BeanDefinition parseCustomElement(Element ele) {
return parseCustomElement(ele, null);
}
// 解析一个非默认命名空间定义的元素
@Nullable
public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
// 获取命名空间资源符
String namespaceUri = getNamespaceURI(ele);
if (namespaceUri == null) {
return null;
}
// 根据命名空间资源符获得对应的解析器
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler == null) {
error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
}
// 解析器解析
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
NamespaceHandlerSupport.parse(Element element, ParserContext parserContext)
查找要解析元素对应的BeanDefinitionParser解析元素。
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
// 找元素对应的解析器:BeanDefinitionParser
BeanDefinitionParser parser = findParserForElement(element, parserContext);
// 根据元素解析bean 注1
return (parser != null ? parser.parse(element, parserContext) : null);
}
@Nullable
private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) {
String localName = parserContext.getDelegate().getLocalName(element);
BeanDefinitionParser parser = this.parsers.get(localName);
if (parser == null) {
parserContext.getReaderContext().fatal(
"Cannot locate BeanDefinitionParser for element [" + localName + "]", element);
}
return parser;
}
注1:不同元素可能对应不同的解析器,如:
元素context:annotation-config对应AnnotationConfigBeanDefinitionParser,具体如何解析见“一起学SF框架系列5.8-模块Beans-注解bean解析2-解析annotation-config”;
元素context:component-scan对应ComponentScanBeanDefinitionParser,具体如何解析见“一起学SF框架系列5.8-模块Beans-Bean注解解析3-解析component-scan”;