一.    spring在解析xml标签时分为默认标签和自定义标签两种。默认标签如bean标签,自定义标签如:aop、tx(关于事物的)、context等。

 二.   

        1.  xml解析是通过BeanDefinitionDocumentReader接口实现的,它只有registerBeanDefinitions一个方法。

spring boot ftl自定义标签_spring源码

      2.  BeanDefinitionDocumentReader的实现类是DefaultBeanDefinitionDocumentReader. 

           1).registerBeanDefinitions方法中调用了doRegisterBeanDefinitions去解析Element,我们知道,spring中doXXX是真正干货的,所以我们进入到doRegisterBeanDefinitions方法;这个方法中又调用了parseBeanDefinitions方法,通过委托模式把Element交给BeanDefinitionParserDelegate解析。 

spring boot ftl自定义标签_spring_02

spring boot ftl自定义标签_spring源码_03


            2).parseBeanDefinitions方法中如果是默认标签,则调用解析默认标签的方法,否则调用解析自定义标签的方法。

spring boot ftl自定义标签_spring_04

            3).解析自定义标签的方法最终调用了BeanDefinitionParserDelegate的parseCustomElement方法;

                第一步:获取到命名空间namespaceUri就是下图xml圈起来的那个URL;

                第二步:根据namespaceUri获取到具体命名空间处理器NamespaceHandler;

                第三步:调用NamespaceHandler的parse方法。

spring boot ftl自定义标签_命名空间_05

spring boot ftl自定义标签_命名空间_06


            4).看看如何获取到具体的命名空间处理器NamespaceHandler的,进入resolve方法。

             第一步:getHandlerMappings获取所有的NamespaceHandler,根据namespaceUri获取具体的handlerOrClassName(NamespaceHandler);

             第二步: handlerOrClassName它可能还没有实例化,只是一个全类名字符串,所以需要反射实例化;

             第三步:获取到具体的处理器后调用init初始化方法,实例化BeanDefinitionParser,并放入 parsers属性中,这个类很重要,一定不要忘了;并把NamespaceHandler对象put放入handlerMappings中。

spring boot ftl自定义标签_spring_07

            5).如何获取到所有的命名空间处理器NamespaceHandler,进入getHandlerMappings方法

               调用PropertiesLoaderUtils.loadAllProperties加载所有的META-INF/spring.handlers文件

,然后put到属性handlerMappings中。

spring boot ftl自定义标签_自定义标签_08

             this.handlerMappingsLocation在哪赋值的?是什么?看下图:

spring boot ftl自定义标签_spring源码_09

         META-INF/spring.handlers文件的路径、格式?

spring boot ftl自定义标签_命名空间_10

spring boot ftl自定义标签_自定义标签_11

           6). 回到NamespaceHandler.parse()方法,进入parse方法。根据Element先获取到BeanDefinitionParser,然后调用parse方法。       

spring boot ftl自定义标签_spring_12

spring boot ftl自定义标签_自定义标签_13

          7). findParserForElement方法根据element获取具体的BeanDefinitionParser解析器。 

spring boot ftl自定义标签_命名空间_14

         8).BeanDefinitionParser.parse()方法就是主要业务了,不同的BeanDefinitionParser干不同的业务。随便看一个,看它干了什么事?

                这个方法很简单:1,调用抽象方法获取了一个BeanDefinition对象,

                                             2,注册BeanDefinition

spring boot ftl自定义标签_自定义标签_15

         至此,整个Spring自定义标签解析已经介绍完了...