美文网首页
1-3自定义标签解析-Spring源码分析

1-3自定义标签解析-Spring源码分析

作者: 呆_fe39 | 来源:发表于2020-02-06 13:47 被阅读0次

    看文章之前 首先问自己几个问题:

    1自定义标签解析是如何实现bean的解析和注册的  

    2自定义标签解析和默认标签解析有何不同

    Spring中标签分为两种: 

         1.Spring默认的标签 如<bean id="account" class

         2.自定义标签  如<aop:aspectj-autoproxy

    对于不同的标签 有不同的处理方式,如下图所示:

    前面我们已经学习了默认标签的解析,那我们今天主要来学习一下自定义标签解析

    首先 进入BeanDefinitionParserDelegate#parseCustomElement(Element, BeanDefinition)方法

    1根据获取的uri去通过DefaultNamespaceHandlerResolver#resolve方法来获取到对应的NamespaceHandler

    我们来看下 DefaultNamespaceHandlerResolver的结构

    通过DefaultNamespaceHandlerResolver我们发现,它本地维护了一个 uri 和对应的handler类全限定名的映射关系如下图所示:

    Class handlerClass = ClassUtils.forName(className, this.classLoader);

    NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);

    通过类名实例化生成对应的NamespaceHandler 并init()进行初始化 然后将初始化的NamespaceHandler存入到映射handlerMappings中替换掉原来的类路径,方便后面的使用 也避免重复初始化

    在看handler.parse(ele, new ParserContext(this.readerContext, this, containingBd))之前我先回顾一下

    我的bean.xml是这样配置如下:

    我现在以<context:component-scan basepackage="com.dfire.soa.practice.testTransation.service.impl"/>为列子:

    点击handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)进入其实是进入了子类NamespaceHandlerSupport去实现了NamespaceHandler.parse()方法,如下图:

    BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext)通过element的localName 获取 对应的BeanDefinitionParser(NamespaceHandlerSupport中本地其实有一个localName和对应解析器的映射关系:

    private final Map<String,BeanDefinitionParser> parsers =new HashMap<>(); 如下图:

    我们可以看到component-scan -> {ComponentScanBeanDefinitionParser@1622} ) 所以parser.parse(element, parserContext)其实就是调用的子类ComponentScanBeanDefinitionParser中的parse方法进行标签的解析 最终注册还是调用了DefaultListableBeanFactory#registerBeanDefinition进行bean的注册

    1BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);

    2registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition())

    3org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition

    其实总结下来自定义标签解析注册 就是通过namespaceuri获取到对应的NamespaceHandler,通过调用父类NamespaceHandlerSupport #parse 获取对应的BeanDefinitionParser解析器 对标签进行解析成BeanDefinitionHolder然后进行注册,其实注册最终都是调DefaultListableBeanFactory#registerBeanDefinition中的注册方法进行注册 ,所谓的注册bean 就是在DefaultListableBeanFactory 维护的beanDefinitionMap中存bean name 和对应的BeanDefinition的关联关系,注册后通知时间监听器 我注册好了!

    相关文章

      网友评论

          本文标题:1-3自定义标签解析-Spring源码分析

          本文链接:https://www.haomeiwen.com/subject/emblyctx.html