Spring自定義標籤的解析
阿新 • • 發佈:2018-12-21
一:專案demo
Spring提供了可擴充套件的支援,利用如下的程式碼來一步步實現spring自定義解析。
專案結構如下,引入spring4.0
1.建立一個user物件
public class User {
private String userName;
private String email;
...............省略getset
}
2.建立一個XSD檔案,用於校驗自定義xml檔案
<?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="userName" type="string"/> <attribute name="email" type="string"/> </complexType> </element> </schema>
3.建立解析類:UserBeanDefinitionParser 繼承AbstractSingleBeanDefinitionParser
public class UserBeanDefinitionParser extends AbstractSingleBeanDefinitionParser { //element對應的類 @Override protected Class getBeanClass(Element element) { return User.class; } //從element中解析並提取對應的元素 @Override protected void doParse(Element element, BeanDefinitionBuilder bean) { String userName = element.getAttribute("userName"); String email = element.getAttribute("email"); //將提取的資料放入到BeanDefinitionBuilder,待完成所有bean的解析後統一註冊到beanfatory中 if (StringUtils.hasText(userName)) { bean.addPropertyValue("userName", userName); } if (StringUtils.hasText(email)) { bean.addPropertyValue("email", email); } } }
4.建立handle,用於將bean注入到spring容器
public class UserNamespaceHandler extends NamespaceHandlerSupport{
@Override
public void init() {
//此處用於解析出來的user標籤交由UserBeanDefinitionParser去處理
registerBeanDefinitionParser("user", new UserBeanDefinitionParser());
}
}
5.建立handle對映檔案,Spring.handlers,以及Spring.schemas用於對xml檔案進行校驗
Spring.handlers
http\://www.lexueba.com/schema/user=spring.tag.handle.UserNamespaceHandler
Spring.schemas
http\://www.lexueba.com/schema/user.xsd=META-INF/user.xsd
6.建立spring配置檔案Spring.xml
注意:beans中的引數需同上handle和schemas相匹配
<?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:usertag="http://www.lexueba.com/schema/user**"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
**http://www.lexueba.com/schema/user http://www.lexueba.com/schema/user.xsd**">
<usertag:user id="user" userName="cosmos" email="[email protected]"/>
</beans>
6.至此,自定義解析步驟完成,開始測試。
public class CustomTagApplication {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
ApplicationContext bf = new ClassPathXmlApplicationContext("spring/tag/xml/Spring.xml");
User user = (User) bf.getBean("user");
System.out.println(user);
}
}
結果如下:
二:原理詳解
在之前bean解析的時候,有兩種方式,如下
自定義標籤會呼叫parseCustomElement方法,parseCustomElement程式碼如下:
名稱空間即為spring.xml中的usertag
通過DefalutNamespaceHandleResolver來載入該bean的處理類,進入DefalutNamespaceHandleResolver下的resolve方法:
載入完handle後,則進入具體的解析過程,呼叫handle的parse方法。此處的parse方法引用的是父類AbstractBeanDefinitionParser的方法,程式碼如下
此處,parseInternal會對bean進行進一步的處理:
到此,自定義標籤的解析就結束了。