小編給大家分享一下Spring自定義XML schema 擴展的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
Spring整合dubbo的事例
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <dubbo:application name="demo-provider"/> <dubbo:registry address="zookeeper://127.0.0.1:2181"/> <dubbo:protocol name="dubbo" port="20890"/> <bean id="demoService" class="org.apache.dubbo.samples.basic.impl.DemoServiceImpl"/> <dubbo:service interface="org.apache.dubbo.samples.basic.api.DemoService" ref="demoService"/> </beans>
上述代碼中我們有看到dubbo自定義了一套自己的標簽,dubbo:application ,dubbo:registry ,dubbo:protocol,dubbo:service我們心中是不是有點小疑問:這些標簽在Spring項目啟動的時候是如何被Spring管理的?是怎樣被Spring來識別的?如果我們自己隨便定義一個標簽Spring是否能夠識別?我們去翻翻Spring的官網發現這玩意其實就是Spring提供的 XML schema 的擴展支持。只要按照它的步驟來,我們就可以配置任何我們自定義的標簽。XML schema 擴展機制是什么?這個也許好多人沒聽過:
★Spring 為基于 XML 構建的應用提供了一種擴展機制,用于定義和配置 Bean。它允許使用者編寫自定義的 XML bean 解析器,并將解析器本身以及最終定義的 Bean 集成到 Spring IOC 容器中。
”
我們可以看看官網https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#xml-custom 10.2. XML Schema Authoring 這個是主要介紹它的。
官網有介紹,要實現一個自定義的XML Schema 總共需要4步:
★編寫一個 XML schema 文件描述的你節點元素。
編寫一個 NamespaceHandler 的實現類
編寫一個或者多個 BeanDefinitionParser 的實現 (關鍵步驟).
注冊上述的 schema 和 handler。
”
既然只要按照這四步來,那我們就照著這個文檔來自己實現一個。
編寫一個javajr.xsd 放入項目的resources/META-INF文件夾里面(這個也可以是其他路徑)
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:tool="http://www.springframework.org/schema/tool" xmlns="https://www.javajr.cn/schema/javajr" targetNamespace="https://www.javajr.cn/schema/javajr"> <xsd:import namespace="http://www.springframework.org/schema/beans"/> <xsd:element name="application"> <xsd:complexType> <xsd:complexContent> <xsd:extension base="beans:identifiedType"> <xsd:attribute name="website" type="xsd:string" use="required"/> <xsd:attribute name="weixin" type="xsd:string" use="required"/> </xsd:extension> </xsd:complexContent> </xsd:complexType> </xsd:element> </xsd:schema>
targetNamespace="https://www.javajr.cn/schema/javajr"
這里targetNamespace的地址后面有用到。
這里我們就定義了一個元素application 里面有兩個屬性分別為website和weixin。
package org.spring.demo.schema;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
public class MyNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
// 這個名字也不是隨便取的,上面編寫xsd的根節點元素的name, <xsd:element name="application">
registerBeanDefinitionParser("application", new MyBeanDefinitionParser());
}
}這個NamespaceHandler 就是將一個 XML 節點解析成 IOC 容器中的一個實體類。也就是說相當于在xml里面的配置的對象,通過Spring ioc 容器管理起來了
package org.spring.demo.schema;
import org.spring.demo.domain.JavajrDomain;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
public class MyBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
@Override
protected Class<?> getBeanClass(Element element) {
return JavajrDomain.class;
}
@Override
protected void doParse(Element element, BeanDefinitionBuilder bean) {
// this however is an optional property
String website = element.getAttribute("website");
if (StringUtils.hasText(website)) {
bean.addPropertyValue("website",website);
}
String weiXin = element.getAttribute("weixin");
if (StringUtils.hasText(weiXin)) {
bean.addPropertyValue("weixin",weiXin);
}
}
}上面在這個實現類只是簡單的做了一個賦值操作,你如果需要有自己的邏輯業務也可以自行來實現。上面還有一個JavajrDomain這個實體類就不貼代碼,就一個簡單的javabean里面包含了兩個屬性weixin和website。
最后在resources/META-INF目錄下添加兩個配置文件(spring.handler和spring.schema):
resources/META-INF/spring.handlers
https\://www.javajr.cn/schema/javajr=org.spring.demo.schema.MyNamespaceHandler
resources/META-IN/spring.schemas
https\://www.javajr.cn/schema/javajr.xsd=META-INF/javajr.xsd
在這個地方的時候我們其實可以以版本號來進行命名,方便我們可以使用多個不同的版本,Spring-beans 就是這么玩的。

在resources 目錄下新建一個applicationContext.xml文件

這個文件就是使用下我們我們自己自定義的schema,這個文件需要注意的就是上面標紅的這幾行,一般如果我們有引入過第三方的框架,比如mq、或者dubbo等它們都有自定義的這些玩意。
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
JavajrDomain bean = ctx.getBean(JavajrDomain.class);
System.out.println(bean.toString());
}我們可以看到控制臺輸出
JavajrDomain{weixin='javajr8', website='javajr.cn'}到這里我們自己實現的一個 XML schema 就完成了,是不是很簡單,只要照著官方文檔擼就可以了。照著擼的過程可能有幾個小細節需要注意下引入 XML schema 的時候需要注意下空格,或者一些特殊符號。上述代碼已經提交到了gitee上https://gitee.com/javajr/spring-schema-demo 感興趣的朋友可以直接下載下來run下,不過還是不建議這么玩,最好還是自己動手去嘗試下,畢竟也就四步,照著文檔來。
在文章開始的時候我們有介紹dubbo 自定義的XML schema ,下面我們一起打開dubbo源碼看看它是如何來實現的,看下面這個截圖,也是按照那四步來的。

現在有了SpringBoot 之后以前用這個 XML schema配置的框架,大多數都會有對應的starter來進行封裝,starter的使用比起 XML schema的使用還是簡單多了,開箱即用,無需編寫很多的配置文件。
以上是“Spring自定義XML schema 擴展的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。