今天看了一下分布式服務框架的那本書,於是里面提到了spring schema的自定義,於是去簡單的了解了一下
參考資源:spring schema擴展: http://www.yihaomen.com/article/java/438.htm
schema定義:http://www.w3school.com.cn/schema/schema_schema.asp
spring schema擴展:http://blog.csdn.net/cutesource/article/details/5864562
spring schema相關字段含義:http://luyuanliang.iteye.com/blog/2154805
在使用分布式服務框架的時候,經常看到有這樣的使用:
<dubbo:service interface="com.unj.dubbotest.provider.DemoService" ref="demoService" />
在很多情況下,我們需要為系統提供可配置化支持,簡單的做法可以直接基於Spring的標准Bean來配置,但配置較為復雜或者需要更多豐富控制的時候,
會顯得非常笨拙。一般的做法會用原生態的方式去解析定義好的xml文件,然后轉化為配置對象,這種方式當然可以解決所有問題,但實現起來比較繁瑣,
特別是是在配置非常復雜的時候,解析工作是一個不得不考慮的負擔。Spring提供了可擴展Schema的支持,這是一個不錯的折中方案,完成一個自定義
配置一般需要以下步驟:
- 設計配置屬性和JavaBean
- 編寫XSD文件
- 編寫NamespaceHandler和BeanDefinitionParser完成解析工作
- 編寫spring.handlers和spring.schemas串聯起所有部件
- 在Bean文件中應用
1、設置配置屬性
package com.springwork.xml; public class People { private String name; private int age; private String id; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getId() { return id; } public void setId(String id) { this.id = id; } }
2、編寫XSD文件
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns="http://www.yihaomen.com/schema/people" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans" targetNamespace="http://www.yihaomen.com/schema/people" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xsd:import namespace="http://www.springframework.org/schema/beans" /> <xsd:element name="people"> <xsd:complexType> <xsd:complexContent> <xsd:extension base="beans:identifiedType"> //復合元素之上以某個復合元素為基礎,然后添加一些元素,具體的解釋看http://www.w3school.com.cn/schema/schema_complex.asp; <xsd:attribute name="name" type="xsd:string" /> <xsd:attribute name="age" type="xsd:int" /> </xsd:extension> </xsd:complexContent> </xsd:complexType> </xsd:element> </xsd:schema>
3、編寫NamespaceHandler和BeanDefinitionParser完成解析工作
package com.springwork.xml; import org.springframework.beans.factory.xml.NamespaceHandlerSupport; public class MyNamespaceHandler extends NamespaceHandlerSupport { public void init() { registerBeanDefinitionParser("people", new PeopleBeanDefinitionParser()); } }
package com.springwork.xml; 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 PeopleBeanDefinitionParser extends AbstractSingleBeanDefinitionParser { protected Class getBeanClass(Element element) { return People.class; } protected void doParse(Element element, BeanDefinitionBuilder bean) { String name = element.getAttribute("name"); String age = element.getAttribute("age"); String id = element.getAttribute("id"); if (StringUtils.hasText(id)) { bean.addPropertyValue("id", id); } if (StringUtils.hasText(name)) { bean.addPropertyValue("name", name); } if (StringUtils.hasText(age)) { bean.addPropertyValue("age", Integer.valueOf(age)); } } }
4、編寫spring.handlers和spring.schemas串聯起所有部件,該文件位於src/META-INF下
http\://www.yihaomen.com/schema/people=com.springwork.xml.MyNamespaceHandler
http\://www.yihaomen.com/schema/people.xsd=com/springwork/xml/people.xsd
5、在Bean文件中應用
將剛才的項目打包為jar,新建項目,導入該jar。編寫spring配置文件
<?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:comtest="http://www.yihaomen.com/schema/people" //和spring.handlers先配置的連接一樣 xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.yihaomen.com/schema/people http://www.yihaomen.com/schema/people.xsd "> <comtest:people id="cutesource" name="一號門" age="1024"/> </beans>
6、測試程序
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.springwork.xml.People; public class Test { public static void main(String[] args) { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext( "classpath:/config/application.xml"); People p = (People) ctx.getBean("cutesource"); System.out.println(p.getId()); System.out.println(p.getName()); System.out.println(p.getAge()); } }
擴展:applicationContext 中 xmlns 與 xsi:schemaLocation 含意
xmlns是XML Namespaces的縮寫,中文名稱是XML(標准通用標記語言的子集)命名空間。 如上圖所示"dog",在有可能產生命名沖突的場合,通過自定義命名空間來解決沖突。
schemaLocation
schemaLocation 屬性用來引用(schema)模式文檔,解析器可以在需要的情況下使用這個文檔對 XML 實例文檔進行校驗。它的值(URI)是成對出現的,第一個值表示命名空間,
第二個值則表示描述該命名空間的模式文檔的具體位置,兩個值之間以空格分隔。當然,在必要情況下,可以為 schemaLocation 屬性指派多個這樣的值對。 如上圖所示。
從上圖可以看到,配置是兩個URL地址,在不連網絡的情況下,或者URL不是真實存在的場合,也可以進行加載,這是因為在META-INF下有兩個配置文件。
通過映射讀取本地信息。如下圖所示。
第一個值表示命名空間,對應的文件是spring.handlers, 告訴spring用哪個類進行解析處理。 第二個值則表示描述該命名空間的模式文檔的具體位置
關於配置示例圖中:cat的映射關系: