一. spring在解析xml标签时分为默认标签和自定义标签两种。默认标签如bean标签,自定义标签如:aop、tx(关于事物的)、context等。
二.
1. xml解析是通过BeanDefinitionDocumentReader接口实现的,它只有registerBeanDefinitions一个方法。
2. BeanDefinitionDocumentReader的实现类是DefaultBeanDefinitionDocumentReader.
1).registerBeanDefinitions方法中调用了doRegisterBeanDefinitions去解析Element,我们知道,spring中doXXX是真正干货的,所以我们进入到doRegisterBeanDefinitions方法;这个方法中又调用了parseBeanDefinitions方法,通过委托模式把Element交给BeanDefinitionParserDelegate解析。
2).parseBeanDefinitions方法中如果是默认标签,则调用解析默认标签的方法,否则调用解析自定义标签的方法。
3).解析自定义标签的方法最终调用了BeanDefinitionParserDelegate的parseCustomElement方法;
第一步:获取到命名空间namespaceUri就是下图xml圈起来的那个URL;
第二步:根据namespaceUri获取到具体命名空间处理器NamespaceHandler;
第三步:调用NamespaceHandler的parse方法。
4).看看如何获取到具体的命名空间处理器NamespaceHandler的,进入resolve方法。
第一步:getHandlerMappings获取所有的NamespaceHandler,根据namespaceUri获取具体的handlerOrClassName(NamespaceHandler);
第二步: handlerOrClassName它可能还没有实例化,只是一个全类名字符串,所以需要反射实例化;
第三步:获取到具体的处理器后调用init初始化方法,实例化BeanDefinitionParser,并放入 parsers属性中,这个类很重要,一定不要忘了;并把NamespaceHandler对象put放入handlerMappings中。
5).如何获取到所有的命名空间处理器NamespaceHandler,进入getHandlerMappings方法
调用PropertiesLoaderUtils.loadAllProperties加载所有的META-INF/spring.handlers文件
,然后put到属性handlerMappings中。
this.handlerMappingsLocation在哪赋值的?是什么?看下图:
META-INF/spring.handlers文件的路径、格式?
6). 回到NamespaceHandler.parse()方法,进入parse方法。根据Element先获取到BeanDefinitionParser,然后调用parse方法。
7). findParserForElement方法根据element获取具体的BeanDefinitionParser解析器。
8).BeanDefinitionParser.parse()方法就是主要业务了,不同的BeanDefinitionParser干不同的业务。随便看一个,看它干了什么事?
这个方法很简单:1,调用抽象方法获取了一个BeanDefinition对象,
2,注册BeanDefinition
至此,整个Spring自定义标签解析已经介绍完了...