引言
最基本的例子,创建一个xmlBeanFactory
创建过程中,xmlBeanFactory会对资源文件进行解析,完成beanFactory创建。
xmlBeanFactory继承机构:
正式开始解析流程:
初始化成员变量:XmlBeanDefinitionReader,并传入当前对象,作用于读取资源文件
调用方法: this.reader.loadBeanDefinitions(resource); 进行资源的加载,完成标签解析,beanDefinition的注册
对resource进行封装到EncodedResource类,可进行编码
if (!currentResources.add(encodedResource)) { 校验当前是否正在重复加载资源文件
真正进行解析资源的方法 # doLoadBeanDefinitions(inputSource, encodedResource.getResource())
通过DefaultdocumentLoader对象加载资源,解析到Docuement对象;
创建 DefaultBeanDefinitionDocumentReader , 调用 registerBeanDefinitions 资源解析;
直接进入 parseBeanDefinitions 方法
分析默认标签解析流程
重点放在bean标签解析 processBeanDefinition(ele, delegate);
重点讲解 默认子标签解析:
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
在这里已经解析,并校验了 id,name 属性 接下来 parseBeanDefinitionElement(ele, beanName, containingBean);
对其他属性 以及子标签进行解析;
#createBeanDefinition 创建BeanDefinition 赋值 设置className
#parseBeanDefinitionAttributes 解析基本属性到 abstractBeanDefinition
parseMetaElements(ele, bd); 解析meta标签数据
解析 <lookup-method/> 在bean运行指定 methodName 时,返回 beanRef
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
解析 <replaced-method/> 替换name属性对应方法, 替换的类需要实现 MethodReplacer 执行方法时,会执行到MethodReplacer#reimplement(Object obj, Method method, Object[] args) 对应方法上;
#parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
解析构造函数
parseConstructorArgElements(ele, bd);
解析property
parsePropertyElements(ele, bd);
解析qualifier
parseQualifierElements(ele, bd);
解析默认标签流程结束;
解析自定义标签:
Aop示例:
指定标签名,注册到命名空间解析器;
public class AopNamespaceHandler extends NamespaceHandlerSupport {
/**
* Register the {@link BeanDefinitionParser BeanDefinitionParsers} for the
* '{@code config}', '{@code spring-configured}', '{@code aspectj-autoproxy}'
* and '{@code scoped-proxy}' tags.
*/
@Override
public void init() {
// In 2.0 XSD as well as in 2.1 XSD.
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
// Only in 2.0 XSD: moved to context namespace as of 2.1
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}
}
命名空间处理器已经找到,并进行注册解析器,那么接下来就开始调用进行解析;
:找到指定解析器,进行解析;
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
BeanDefinitionParser parser = findParserForElement(element, parserContext);
return (parser != null ? parser.parse(element, parserContext) : null);
}
/**
* Locates the {@link BeanDefinitionParser} from the register implementations using
* the local name of the supplied {@link Element}.
*/
@Nullable
private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) {
//通过 aa:aspectj-autoproxy -> aspectj-autoproxy 找到指定解析器返回
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;
}
示例 AspectJAutoProxyBeanDefinitionParser 重写 parse方法进行自定义解析,返回BeanDefinition;
自定义解析已经完成;