如何应用Spring handlers技术?

开课吧小白2021-07-20 18:19

我们在日常使用Spring框架时,可能会遇到需要将XML配置的文件转化成Bean,目的是想让它来继续提供程序运作。这项技术就叫做Spring handlers技术。接下来我们就介绍具体是怎样解析标签的。

1.原理

spring容器的启动入口是下图的

AbstractApplicationContext.refresh()方法。由于spring程序使用的是XML配置,所以真正的容器类是ClassPathXmlApplicationContext

Java

然后经过下面的一系列的方法调用,会执行到

BeanDefinitionDelegate.parseCustomElement(Element,BeanDefinition)方法去解析XML中具体的标签。其中Element参数就是<tx:annotation-driven transaction-manager="txManager"/>,其中<tx>叫做命名空间(namespace)

Java

下图是

BeanDefinitionDelegate.parseCustomElement(Element,BeanDefinition)内部的具体调用细节。

Java

这张图蕴含着spring handlers三个重要的接口,NamespaceHandlerResolver、NamespaceHanlder、BeanDefinitionParser。我们以上图的调用顺序图来说明例子。

首先方法parseCustomElement通过

XmlReaderContext.getNamespaceHandlerResolver()方法获取NamespaceHandlerResolver。该类的作用是通过URI(<tx>标签的URI为:http

://www.springframework.org/schema/tx,也就是其XML文件中的头部)获取到处理这个命名空间的NamespaceHandler

 

Java

然后通过NamespaceHandler.parse()方法获取到处理这个元素的BeanDefinitionParser,这里也就是annotation-driver这个元素。

NamespaceHandler的主要作用就是注册与查找处理特定元素的BeanDefinitionParser。其中init()方法一般是用来注册处理特定标签元素的BeanDefinitionParser。spring提供了一个NamespaceHandlerSupport作为实现NamespaceSupport的一个基类,自定义的NameSpaceHandler可以直接继承NamespaceHandlerSUpport。

Java

得到BeanDefinitionParser后,再调用其parse()方法来具体解析XML元素中的属性,进一步生成BeanDefinition

spring容器就可以用上面生成的BeanDefinition来生成Bean。

问题:NamespaceHandlerResolver如何找到并且维护URI和NamespaceHandler的关系?

spring提供了一个默认实现

DefaultNamespaceHandlerResolver,该类的作用是从classpath中的jar包META-INF/spring.handlers文件中加载URI和其对应的NamespaceHandler,并且维护其映射。代码如下:

Java

可以看到该类默认是从META-INF/spring.handlers文件加载映射关系,并且放到handlerMappings字段保存。

Java

该方法首先通过getHandlerMappings()获取到所有的URI-NamespaceHandler对应关系,然后再将其实例化,最后放到handlerMappings字段中。其中spring handler技术的加载策略就在getHandlerMappings()中

Java

可以看到该方法就是通过

PropertiesLoaderUtils.loadAllProperties(this.handlerMappingsLocation,this.classLoader)方法将其加载进来。

所以要想改变spring handler的加载行为和策略,可以自定义NamespaceHandlerResolver然后重写resolve方法!

下图是

DefaultNamespaceHandlerResolver的一个逻辑总结:DefaultNamespaceHandlerResolver从classpath的Jar包下的META-INF/spring.handlers文件下加载映射关系。并保存。

Java

spring handler技术规定jar包下要有两个文件,spring handlers文件和spring.schemas文件,其中spring.handlers文件里面是URI和其对应的NamespaceHandler映射。spring.schemas文件内容是URI对应的schema文件位置。

 

Java

Java

Java

2.策略模式在spring handlers中的使用

在一个Spring程序中,不仅有spring容器的标签,而且还有公司或者第三方自定义的标签,每个标签都要有自己的解析方式,那么spring是怎么解决这个问题的呢?

首先spring定义了上面提到的标签解析流程,提供了一套解析标签的具体框架和接口。

如果用户想创建自己的标签,那么直接继承NamespaceHandlerSupport接口就好,可以看到其子类繁多。都是处理不同的命名空间的。

Java

3.如何编写自定义XML文件在Spring容器中使用

step1.写XSD文件,规定要使用的XML文件中可以使用的元素规则

step2.创建NamespaceHandler,用来注册BeanDefinitionParse

step3.创建BeanDefinitionParse具体来解析元素,并生成BeanDefinition对象

step4.打包,在META-INF文件下创建spring.handlers和spring.schemas文件,文件内容填写相应的值

4.总结和启发

spring handlers技术的SPI思想值得学习。

策略模式的使用

5.其它

github主页:

https://github.com/youngFF

git仓库地址:

https://github.com/youngFF/MyHearthStone.git

gitbook地址:

https://youngff.github.io/MyHearthStone/

以上就是开课吧广场小编为大家整理发布的“如何应用Spring handlers技术?”一文,想要了解提升更多职场软技能,前往开课吧广场-职场软技能查看!

免责声明:本站所提供的内容均来源于网友提供或网络搜集,由本站编辑整理,仅供个人研究、交流学习使用。如涉及版权问题,请联系本站管理员予以更改或删除。
有用
分享