Spring自定义标签使用及原理

  • Post author:
  • Post category:其他


最近大半年一直在看spring的源码,寻思着需要写点什么,也锻炼下自己文档编写的能力。本篇我们讲解spring自定义标签的使用及原理,分为以下小节进行讲解。

  1. 自定义标签的用途
  2. 自定义标签使用
  3. 自定义标签如何被spring解析

    1.自定义标签的用途


自定义标签可以说是spring提供的最大、最强的Hook(钩子),通俗的讲就是给后续小伙伴开发组件,提供一个标准公共可拔插”接口”,大家可以理解为手机充电器的工业标准口,为了方便各个充电器生产厂家生产,而制定的标准。

既然说自定义标签如此强大,我们在哪里应用的呢? 我们知道spring发展越来越强大,但核心的组件只有spring-core和spring-beans,那么有些人会问我们经常用的context,aop,tx不是吗?对的,这些都是在核心上做的扩展,而这些扩展恰恰是通过自定义标签实现扩展的,还有一些公共开源组件amq,redis,dubbo等等,他们都利用了自定义标签来扩展,使得spring容器的功能越发强大。

2.自定义标签使用


既然自定义标签用途那么广,那么如何使用自定义标签呢?这里我将带领大家感受下自定义标签的使用。需要的文件(按照spring加载、解析的顺序)有以下五个基本文件:

①spring.schemas

②XSD文件

③spring.handlers



NamespaceHandler




BeanDefinitionParser


⑥最后引入到配置文件中使用。

基本自定义标签需要实现两个关键接口:NamespaceHandlerSupport,BeanDefinitionParser

先看下基本工程代码结构:

这里写图片描述

①spring.schemas是告诉spring容器我们的自定义的xsd文件在哪里,内容如下

这里写图片描述

类似与key=value的形式。如果找不到会去网络上下载。

②我们知道DTD与XSD是spring中最常见的切基础的配置文件,打个比方DTD类似于Java的关键字,而XSD则类似于Java的语法。

而我们自定义XSD文件则是对于我们定义bean对象时可以使用的属性限制或者说支持的那些属性配置,自定义的spring-custom.xsd如下:

这里写图片描述

指定namespace时,请勿使用spring默认前缀。

这里我们定义了一个element属性可以设置id,pointcut.

③Handlers作为自定义标签解析的入口需要在默认文件名称spring.handlers指定,文件内容如下:

这里是我们自定义的NamespaceHandlers.目的是为了注册我们对应标签的解析类;

这里写图片描述

④BeanDefinitionParser

这里我们不直接实现这个接口,我们直接使用他的抽象实现类

AbstractSingleBeanDefinitionParser

。这里我们获取属性并设置到bean中。

这里写图片描述

这里写图片描述

⑤自定义标签的使用

这里写图片描述

⑥工程代码


点这里


⑦Aop及tx也是通过自定义标签来扩展容器能力的

AOP扩展解析入口为

AopNamespaceHandlers


这里写图片描述

声明式事务tx解析入口为:

TxNamespaceHandler


这里写图片描述

Context解析入口为:

ContextNamespaceHandler


这里写图片描述

以上我们都可以看到我们配置的属性代码中对应的

BeanDefinitionParser

3.自定义标签如何被spring解析


这里涉及到整个spring容器对于xml文件的解析过程,理解起来可能会有点困难,但我会尽量给大家做通俗易懂的介绍。

我们只介绍spring对于配置文件的解析过程,不介绍bean对象的实例化,初始化,及管理过程。

我们先介绍几个基础知识

①我们经常说的spring容器到底指什么,以及如何存储我们配置bean属性?

基础容器

BeanFactory

,扩展容器

ApplicationContext

,他们解析配置文件的过程基本相同。

存储结构为

Map<beanName, BeanDefinition>

实现为

ConcurrentHashMap

,也就是说我们最终解析出来的xml文件的会存储到这个数据结构中,这就是我们的容器。

②我们解析出配置问文件用哪个对象来接收存储?

我们知道在抽象对象世界里everything is object.所以我们将bean抽象成了对象,它的顶层接口就是

BeanDefinition

,而子类包括了

ChildBeanDefinition



RootBeanDefinition



GenericBeanDefinition

,默认文件解析入Map为

GenericBeanDefinition

.

③Spring基础标签有哪些?

这里写图片描述


Import, alias, bean, beans

④Spring配置文件的解析入口在哪?

这里介绍两个重要的接口及其实现类


BeanDefinitionReader



BeanDefinitionDocumentReader


对应实现类

XmlBeanDefinitionReader



DefaultBeanDefinitionDocumentReader


这里写图片描述

这里写图片描述

⑤自定义标签的解析过程

这里写图片描述

这里最关键的步骤是

DefaultBeanDefinitionDocumentReade

r类中私有方法

这里写图片描述

上图即显示了默认标签和自定义标签的不同解析方式。

而自定义标签的解析需要借助Delegates获取namespaceuri然后,加载我们配置的spring.handlers文件内容,获取我们指定好的

NamespaceHandler

,然后调用parse方法初始化的init方法将

BeanDefinitionParser

初始化到parsers类型为map容器中,然后我们根据localName获取对应的

BeanDefinitionParser

,进行element的进一步解析。

这个过程就完成了自定义标签的文件的解析了。



版权声明:本文为zzg1229059735原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。