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

2020-02-06  本文已影响0人  呆_fe39

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

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的关联关系,注册后通知时间监听器 我注册好了!

上一篇 下一篇

猜你喜欢

热点阅读