天天看点

Spring进阶之自定义标签实现 Spring进阶之自定义标签实现

Spring进阶之自定义标签实现

头条号:不止于知识 使用过dubbo的人应该都配置过类似:

<dubbo:service inter ref="demoService" />

<dubbo:reference id="demoService" inter />

那这些dubbo标签是怎么让spring容器识别的呢?

42.1 Introduction

Since version 2.0, Spring has featured a mechanism for schema-based extensions to the basic Spring XML format for defining and configuring beans. This section is devoted to detailing how you would go about writing your own custom XML bean definition parsers and integrating such parsers into the Spring IoC container.

To facilitate the authoring of configuration files using a schema-aware XML editor, Spring’s extensible XML configuration mechanism is based on XML Schema. If you are not familiar with Spring’s current XML configuration extensions that come with the standard Spring distribution, please first read the appendix entitled???.

Creating new XML configuration extensions can be done by following these (relatively) simple steps:

  • Authoring an XML schema to describe your custom element(s).
  • Coding a custom 

    NamespaceHandler

     implementation (this is an easy step, don’t worry).
  • Coding one or more 

    BeanDefinitionParser

     implementations (this is where the real work is done).
  • Registering the above artifacts with Spring (this too is an easy step).

spring官方文档中42.1点介绍中有详细说明怎么自定义标签,简单的来说自定义标签就是:

  1. 编写一个xml架构来描述自定义的元素

<xsd:element name="service" type="serviceType">

<xsd:annotation>

<xsd:documentation><![CDATA[ Export service config ]]></xsd:documentation>

</xsd:annotation>

</xsd:element>

<xsd:complexType name="serviceType">

<xsd:extension base="abstractServiceType">

<xsd:attribute name="interface" type="xsd:token" use="required">

........

<xsd:annotation>

<xsd:documentation>描述</xsd:documentation>

<xsd:appinfo>

<tool:annotation>

<tool:expected-type type="java.lang.Class"/>

</tool:annotation>

</xsd:appinfo>

</xsd:annotation>

........

</xsd:attribute>

</xsd:extension>

</xsd:complexType>

编写一个自定义的handler实现NamespaceHandler接口

//NamespaceHandlerSupport实现了NamespaceHandler接口

public class DubboNamespaceHandler extends NamespaceHandlerSupport {

public void init() {

registerBeanDefinitionParser("application"

, new DubboBeanDefinitionParser(ApplicationConfig.class,true);

}

}

编写一个或者多个自定义的解析器实现BeanDefinitionParser接口

以上DubboBeanDefinitionParser.class则是自定义的解析器

注册到Spring容器

通过registerBeanDefinitionParser(String elementName, BeanDefinitionParser parser)方法

elementName:注册到spring容器的名称

parser:解析器,解析xml元素实例化对象

完成上述准备工作了,怎么让spring容器加载呢?

42.5 Registering the handler and the schema

The coding is finished! All that remains to be done is to somehow make the Spring XML parsing infrastructure aware of our custom element; we do this by registering our custom 

namespaceHandler

 and custom XSD file in two special purpose properties files. These properties files are both placed in a 

'META-INF'

 directory in your application, and can, for example, be distributed alongside your binary classes in a JAR file. The Spring XML parsing infrastructure will automatically pick up your new extension by consuming these special properties files, the formats of which are detailed below.

42.5.1 'META-INF/spring.handlers'

The properties file called 

'spring.handlers'

 contains a mapping of XML Schema URIs to namespace handler classes. So for our example, we need to write the following:

http\://www.mycompany.com/schema/myns=org.springframework.samples.xml.MyNamespaceHandler

(The 

':'

 character is a valid delimiter in the Java properties format, and so the 

':'

 character in the URI needs to be escaped with a backslash.)

The first part (the key) of the key-value pair is the URI associated with your custom namespace extension, and needs to match exactly the value of the 

'targetNamespace'

 attribute as specified in your custom XSD schema.

42.5.2 'META-INF/spring.schemas'

The properties file called 

'spring.schemas'

 contains a mapping of XML Schema locations (referred to along with the schema declaration in XML files that use the schema as part of the 

'xsi:schemaLocation'

 attribute) to classpath resources. This file is needed to prevent Spring from absolutely having to use a default 

EntityResolver

 that requires Internet access to retrieve the schema file. If you specify the mapping in this properties file, Spring will search for the schema on the classpath (in this case 

'myns.xsd'

 in the 

'org.springframework.samples.xml'

 package):

http\://www.mycompany.com/schema/myns/myns.xsd=org/springframework/samples/xml/myns.xsd

The upshot of this is that you are encouraged to deploy your XSD file(s) right alongside the 

NamespaceHandler

 and 

BeanDefinitionParser

 classes on the classpath.

spring官方文档在42.5*中有详细介绍,简单来说就是:

1.上述定义好的自定义元素描述文件文件(xsd)放置到META-INF目录下:

例如:dubbo.xsd

2.定义好spring.handlers文件放置到META-INF目录下

内容样式:http\://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler

key:是你的命名空间,其他xml中通过引入这个命名空间进行使用该元素描述对象

value:指向的是你的handler

3.定义好spring.schemas文件放置到META-INF目录下:

内容样式:

http\://code.alibabatech.com/schema/dubbo/dubbo.xsd=META-INF/dubbo.xsd

key:指向xsd的地址

value:具体文件

文件结构展示:

Spring进阶之自定义标签实现 Spring进阶之自定义标签实现

测试:

1.引入自定义的标签命名空间,定义自定义元素描述

Spring进阶之自定义标签实现 Spring进阶之自定义标签实现

2.加载配置,获取testBean

Spring进阶之自定义标签实现 Spring进阶之自定义标签实现

从结果看到自定义的标签已经生效。了解了spring自定义标签,在工作中需要的话,也可以为自己自定义标签啦~