一,前言
之前記錄過一篇關于spring預設标簽解析及注冊實作的文章。
這次記錄自定義标簽來結合那篇文章加深了解
二,正文
首先我們來理一理如何自定義一個spring的标簽,像bean标簽那樣使用,我們先概覽一些整體的流程:
- 建立一個需要擴充的元件
- 定義一個XSD檔案,描述元件内容
- 建立一個java類,實作BeanDefinitionParser接口,用來解析XSD檔案中的定義群組件定義
- 建立一個Handler類,擴充
,目的是将元件注冊到容器。NameSpaceHandlerSupport
- 編寫(添加)
檔案。Spring.handlers和Spring.schemas
完成以上工作的話,那麼我們就可以使用我們自定義的标簽了。
1,建立pojo類
public class User {
private String name;
private String sex;
private String email;
private String id;
//set get method...
}
2,定義一個xsd檔案描述元件類容
以前spring使用的是dtd檔案,現在幾乎使用的都是xsd檔案了,xsd檔案的定義如果不了解的朋友可以去 http://www.phpstudy.net/e/schema/ 這個網址看看,用法比較簡單,這裡就不介紹如何使用了,下面是按照schema的規則定義一個xsd檔案
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.lexueba.com/schema/user"
xmlns:tns="http://www.lexueba.com/schema/user"
elementFormDefault="qualified">
<element name="user">
<complexType>
<attribute name="id" type="string" />
<attribute name="name" type="string" />
<attribute name="sex" type="string" />
<attribute name="email" type="string" />
</complexType>
</element>
</schema>
3,實作AbstractSingleBeanDefinitionParser接口
實作了這個接口,當spring加載文檔的時候,遇到你定義的标簽,他就會回調你的這個解析方法,進行你自定義的屬性解析。
public class UserBeanDefinitionParser extends AbstractSingleBeanDefinitionParser{
@Override
protected Class<?> getBeanClass(Element element) {
return User.class;
}
//從elelment中解析并提取對應的元素
@Override
protected void doParse(Element element, BeanDefinitionBuilder builder) {
String name=element.getAttribute("name");
String email=element.getAttribute("sex");
String sex=element.getAttribute("sex");
//将提取到的資料放入beanDefinitionBuilder 中,待完成所有的bean解析後統一放到beanfactory
if(StringUtils.hasText(name)){
builder.addPropertyValue("name", name);
}
if(StringUtils.hasText(email)){
builder.addPropertyValue("email", email);
}
if(StringUtils.hasText(sex)){
builder.addPropertyValue("sex", sex);
}
}
}
4,繼承抽象類NamespaceHandlerSupport
定義了标簽,這裡就是标簽的處理器,處理器中會把解析類
(UserBeanDefinitionParser)
的執行個體傳入spring中,使得當spring解析到該标簽的時候可以回調該執行個體的方法。
public class MyNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
registerBeanDefinitionParser("user", new UserBeanDefinitionParser());
}
}
5,修改(添加)spring.handlers檔案和spring.schemas檔案
這兩個檔案預設路徑是在spring-aop的META-INF這個路徑下面
http\://www.lexueba.com/schema/user
(自定義的)=
net.itaem.handler.MyNamespaceHandler
修改spring.schemas檔案的内容,添加以下内容
http\://www.lexueba.com/schema/user.xsd
(自定義的)=
org/springframework/beans/factory/xml/use.xsd
修改好之後在使用自定義标簽的時候便會把這些加到xsi:schemaLocation裡面去,然後spring會自己去找xsd檔案以及處理器(handler)
6,建立測試配置檔案
使用的時候可以加上自己定義的命名空間,然後再
xsi:schemaLocation
加上對應的内容,就可以使用自己定義的标簽了。
<?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:myname="http://www.lexueba.com/schema/user"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.lexueba.com/schema/user http://www.lexueba.com/schema/user.xsd">
<myname:user id="beantest" name="whx" email="[email protected]" sex="男"/>
</beans>
7,編寫測試代碼
public class Test {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("net/itaem/source/custom_user.xml");
User bt=(User) context.getBean("beantest");
System.out.println(bt);
}
}