Spring XML Schema擴(kuò)展機(jī)制的使用示例
前言
在當(dāng)前Java生態(tài),Spring算的上是最核心的框架,所有的開(kāi)發(fā)組件想要得到大范圍更便捷的使用,都要和Spring進(jìn)行整合,比如我們熟知的Mybatis、Dubbo等,以及內(nèi)部封裝的各類(lèi)組件包括Redis、MQ、配置中心等。
有了整合這一步,我們只需引入相應(yīng)的jar,比如mybatis-spring,然后進(jìn)行簡(jiǎn)單的配置后即可在Spring工程中使用Mybatis的功能,也正是由于這樣的便捷性,導(dǎo)致很多時(shí)候我們沒(méi)有對(duì)其進(jìn)行深究。
XML Schema擴(kuò)展
打開(kāi)mybatis-spring、dubbo的源碼會(huì)發(fā)現(xiàn)在META-INF目錄下有兩個(gè)文件(如下圖所示),spring.handlers與spring.schemas,這兩個(gè)文件就是XML Schema擴(kuò)展的關(guān)鍵入口點(diǎn)。
XSD
XSD,XML Schema Definition,XML定義。
XML Schema定義XML文檔的結(jié)構(gòu),XML Schema語(yǔ)言也稱(chēng)為XML定義,即XSD。
簡(jiǎn)單的說(shuō),XSD用于制定xml文件規(guī)范,包括xml中的元素(簡(jiǎn)單元素、復(fù)雜元素)、屬性、以及屬性類(lèi)型及約束等。
Spring XML Schema擴(kuò)展的第一步就是要定義一個(gè)xsd文件,比如spring-beans對(duì)應(yīng)xsd文件為http://www.springframework.org/schema/beans/spring-beans.xsd,如下圖:
為了簡(jiǎn)單介紹Spring XML Schema擴(kuò)展實(shí)現(xiàn),下面將一個(gè)簡(jiǎn)單例子(模擬一個(gè)簡(jiǎn)單的分布式id生成器,不會(huì)實(shí)現(xiàn)具體功能)進(jìn)行說(shuō)明,xsd定義如下(文件命名為DistributedId.xsd,在META-INF目錄下):
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns="http://www.hexup.com/schema/distributed-id" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.hexup.com/schema/distributed-id"> <xsd:element name="distributed-id"> <xsd:complexType> <xsd:attribute name="id" type="xsd:string"></xsd:attribute> <xsd:attribute name="bizCode" type="xsd:string"></xsd:attribute> <xsd:attribute name="length" type="xsd:int"></xsd:attribute> </xsd:complexType> </xsd:element> </xsd:schema>
上述xsd文件里定義了一個(gè)復(fù)雜元素distributed-id,包含屬性id,bizCode,length,形如:
<distributed-id id="xxx" bizCode="xxx" length="xxx"></distributed-id>
注意:xmlns,即為xml namespace,xml命名空間,后面跟的http鏈接地址可以不存在,因?yàn)閤sd會(huì)放在當(dāng)前工程的META-INF下。
配置spring.handlers和spring.schemas
如下兩張圖所示,spring.schemas文件中用于說(shuō)明xsd的文件路徑,spring.schemas文件用于說(shuō)明解析此類(lèi)xsd定義的標(biāo)簽的處理類(lèi),下面會(huì)對(duì)處理類(lèi)進(jìn)行詳細(xì)說(shuō)明。
NameSpaceHandler與BeanDefinitionParser
定義類(lèi)DistributedIdNamespaceHandler繼承NamespaceHandlerSupport,init方法用于注冊(cè)BeanDefinition解析器,也就是解析xml中對(duì)應(yīng)標(biāo)簽為Spring Bean。
public class DistributedIdNamespaceHandler extends NamespaceHandlerSupport { @Override public void init() { registerBeanDefinitionParser("distributed-id", new DistributedIdParser()); } }
同時(shí)要?jiǎng)?chuàng)建BeanDefinitionParser
public class DistributedIdParser implements BeanDefinitionParser { @Override public BeanDefinition parse(Element element, ParserContext parserContext) { // 解析xml內(nèi)的標(biāo)簽 String bizCode = element.getAttribute("bizCode"); int length = Integer.valueOf(element.getAttribute("length")); String id = element.getAttribute("id"); // 創(chuàng)建DistributedIdFactoryBean bean BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(); builder.getRawBeanDefinition().setBeanClass(DistributedIdFactoryBean.class); builder.setScope(BeanDefinition.SCOPE_SINGLETON); builder.addPropertyValue("bizCode", bizCode); builder.addPropertyValue("length", length); BeanDefinition beanDefinition = builder.getBeanDefinition(); parserContext.getRegistry().registerBeanDefinition(id, beanDefinition); return beanDefinition; } }
其中DistributedIdFactoryBean實(shí)現(xiàn)FactoryBean接口用于創(chuàng)建DistributedIdComponent Bean,如下
public class DistributedIdFactoryBean implements InitializingBean, FactoryBean<DistributedIdComponent> { private String bizCode; private int length; private DistributedIdComponent distributedIdComponent; @Override public DistributedIdComponent getObject() throws Exception { return distributedIdComponent; } @Override public Class<?> getObjectType() { return DistributedIdComponent.class; } @Override public boolean isSingleton() { return false; } @Override public void afterPropertiesSet() throws Exception { distributedIdComponent = new DistributedIdComponent(bizCode, length); } public void setBizCode(String bizCode) { this.bizCode = bizCode; } public void setLength(int length) { this.length = length; } }
目標(biāo)Bean DistributedIdComponent如下:
public class DistributedIdComponent { private String bizCode; private int length; public DistributedIdComponent() { } public DistributedIdComponent(String bizCode, int length) { this.bizCode = bizCode; this.length = length; } public String generateId() { System.out.println("mock generate id"); return String.valueOf(System.currentTimeMillis()).substring(0, length); } public String getBizCode() { return bizCode; } public void setBizCode(String bizCode) { this.bizCode = bizCode; } public int getLength() { return length; } public void setLength(int length) { this.length = length; } }
使用
spring配置文件,spring-service.xml中配置distributed-id標(biāo)簽以及對(duì)應(yīng)的屬性值,如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:distributed-id="http://www.hexup.com/schema/distributed-id" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.hexup.com/schema/distributed-id http://www.hexup.com/schema/distributed-id.xsd"> <distributed-id:distributed-id id="test" bizCode="test" length="8"></distributed-id:distributed-id> </beans>
運(yùn)行容器驗(yàn)證:
public class App { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-service.xml"); DistributedIdComponent bean = context.getBean(DistributedIdComponent.class); String id = bean.generateId(); System.out.println("id:" + id); } }
總結(jié)
本文主要介紹了Spring XML Schema擴(kuò)展機(jī)制的使用方法,大致步驟為定義XSD文件、配置spring.schemas、編碼實(shí)現(xiàn)NameSpaceHanlder和BeanDefinitionParser實(shí)現(xiàn)類(lèi)、配置spring.handlers。但未說(shuō)明具體的實(shí)現(xiàn)原理,后續(xù)會(huì)有一篇文章詳細(xì)介紹Spring源碼是怎么實(shí)現(xiàn)擴(kuò)展的,以及介紹為什么使用FactoryBean來(lái)創(chuàng)建具體的Bean等問(wèn)題。
以上就是Spring XML Schema擴(kuò)展機(jī)制的使用示例的詳細(xì)內(nèi)容,更多關(guān)于Spring XML Schema擴(kuò)展機(jī)制的使用的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Spring中XML schema擴(kuò)展機(jī)制的深入講解
- SpringBoot配置logback.xml 多環(huán)境的操作步驟
- spring*.xml配置文件明文加密的實(shí)現(xiàn)
- 使用maven開(kāi)發(fā)springboot項(xiàng)目時(shí)pom.xml常用配置(推薦)
- SpringBoot整合Mybatis無(wú)法掃描xml文件的解決
- 解決Spring boot整合mybatis,xml資源文件放置及路徑配置問(wèn)題
- 關(guān)于Spring自定義XML schema 擴(kuò)展的問(wèn)題(Spring面試高頻題)
- 如何擴(kuò)展Spring Cache實(shí)現(xiàn)支持多級(jí)緩存
- Springboot啟動(dòng)擴(kuò)展點(diǎn)超詳細(xì)教程小結(jié)
相關(guān)文章
Java 1.8使用數(shù)組實(shí)現(xiàn)循環(huán)隊(duì)列
這篇文章主要為大家詳細(xì)介紹了Java 1.8使用數(shù)組實(shí)現(xiàn)循環(huán)隊(duì)列,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-10-10Spring?Cloud負(fù)載均衡組件Ribbon原理解析
本文主要講述了微服務(wù)體系下的?Spring?Cloud?Netflix?套件中?Ribbon?的使用,并結(jié)合部分源碼講述了?Ribbon?的底層原理,重點(diǎn)講述了?Ribbon?中是如何獲取服務(wù)以及如何判定一個(gè)服務(wù)是否可用,最后也介紹了?Ribbon?中默認(rèn)提供的?7?種負(fù)載均衡策略,感興趣的朋友一起看看吧2022-04-04Spring實(shí)戰(zhàn)之Bean的作用域singleton和prototype用法分析
這篇文章主要介紹了Spring實(shí)戰(zhàn)之Bean的作用域singleton和prototype用法,結(jié)合實(shí)例形式分析了Bean的作用域singleton和prototype相關(guān)使用方法及操作注意事項(xiàng),需要的朋友可以參考下2019-11-11java多線程編程之使用runnable接口創(chuàng)建線程
實(shí)現(xiàn)Runnable接口的類(lèi)必須使用Thread類(lèi)的實(shí)例才能創(chuàng)建線程,通過(guò)Runnable接口創(chuàng)建線程分為以下兩步2014-01-01Java線程本地變量導(dǎo)致的緩存問(wèn)題解決方法
使用緩存可以緩解大流量壓力,顯著提高程序的性能,我們?cè)谑褂镁彺嫦到y(tǒng)時(shí),尤其是大并發(fā)情況下,經(jīng)常會(huì)遇到一些疑難雜癥,這篇文章主要給大家介紹了關(guān)于Java線程本地變量導(dǎo)致的緩存問(wèn)題的解決方法,需要的朋友可以參考下,2024-08-08Java中類(lèi)的初始化和實(shí)例化區(qū)別詳解
這篇文章主要介紹了Java中類(lèi)的初始化和實(shí)例化區(qū)別詳解,類(lèi)的初始化<BR>是完成程序執(zhí)行前的準(zhǔn)備工作,類(lèi)的實(shí)例化(實(shí)例化對(duì)象)是指創(chuàng)建一個(gè)對(duì)象的過(guò)程,需要的朋友可以參考下2023-08-08