Spring中的NamespaceHandler与BeanDefinitionParser详解
1.前文
由Spring启动过程之-obtainFreshBeanFactory()
可以看到NamespaceHandler、BeanDefinitionParser为解析配置文件中的Element起重要作用。
那么它本身是如何被加载的呢?
2.NamespaceHandler之ContextNamespaceHandler
常见的NamespaceHandler实例:ContextNamespaceHandler
很明显能看出有常用的 context:annotation-config/、<context:component-scan base-package=“xx”/>、context:property-placeholder/对应的解析类。
3.BeanDefinitionParser的作用
解析相关节点,并注册BeanDefinition。
3.1 PropertyPlaceholderBeanDefinitionParser
大致流程为解析<context:property-placeholder location="classpath:module.properties" />节点,包装PropertySourcesPlaceholderConfigurer为BeanDefinition,将里面的属性装配到BeanDefinition中,并注册到BeanDefinitionMap。
PropertyPlaceholderBeanDefinitionParser#parse: AbstractBeanDefinitionParser-> parseInternal-> BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();//创建BeanDefinition ... builder.getRawBeanDefinition().setBeanClass(PropertySourcesPlaceholderConfigurer.class); ... doParse(element, parserContext, builder)-> super.doParse(element, parserContext, builder);//解析公共属性:location,fileEncoding等 ....//做特殊属性的解析 return builder.getBeanDefinition(); //统一注册 registerBeanDefinition(holder, parserContext.getRegistry());
3.2 ComponentScanBeanDefinitionParser
解析节点<context:component-scan base-package="com.gkwind"/>本身。并根据其配置,做特殊的class扫描,将符合配置的class,如被@Component标记过的类 包装成BeanDefinition,注入到BeanDefinitionMap中。 注意这里做的工作是根据配置,扫描加载了配置对应的多个类
ComponentScanBeanDefinitionParser#parse流程
NamespaceHandler 加载过程
跟踪源码, 可以发现解析非自定义命名空间parseCustomElement时会调用DefaultNamespaceHandlerResolver#resolve,然后resolve得到的所有NamespaceHandler。之后得到命名空间对应的NamespaceHandler 再NamespaceHandler#init初始化相关的parser。
getHandlerMappings以SPI的方式得到所有spring.handlers
NamespaceHandler 加载流程
作用:可实现自定义标签
知道了NamespaceHandler与BeanDefinitionParser作用后, 我们可以自定义schema,然后在spring的xml中自定义命名空间thewindkee标签<thewindkeetag>,再实现thewindkee对应的NamespaceHandler与<thewindkeetag>的BeanDefinitionParser,最后将NamespaceHandler配置到META-INF/spring.handlers。
大致Java代码:
class TheWindKeeNamespaceHandler extends NamespaceHandlerSupport { public void init(){ registerBeanDefinitionParser("thewindkeetag", new TheWindKeeTagBeanDefinitionParser()); } } class TheWindKeeTagBeanDefinitionParser extends AbstractBeanDefinitionParser{ public final BeanDefinition parse(Element element, ParserContext parserContext) { //解析element .... //注册BeanDefinition registerBeanDefinition(holder, parserContext.getRegistry()); } }
到此这篇关于Spring中的NamespaceHandler与BeanDefinitionParser详解的文章就介绍到这了,更多相关NamespaceHandler与BeanDefinitionParser内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
深入了解Java中String、Char和Int之间的相互转换
这篇文章主要介绍了深入了解Java中String、Char和Int之间的相互转换,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,,需要的朋友可以参考下2019-06-06Spring MVC DispatcherServlet处理请求过程示例详解
这篇文章主要介绍了Spring MVC DispatcherServlet处理请求过程示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2023-09-09java微信小程序步数encryptedData和开放数据解密的实现
这篇文章主要介绍了java微信小程序步数encryptedData和开放数据解密的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2020-09-09
最新评论