天天看點

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自定義标簽,在工作中需要的話,也可以為自己自定義标簽啦~