最基本的例子,创建一个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;
自定义解析已经完成;