天天看點

spring - 自定義标簽實作及使用

一,前言

之前記錄過一篇關于spring預設标簽解析及注冊實作的文章。

這次記錄自定義标簽來結合那篇文章加深了解

二,正文

首先我們來理一理如何自定義一個spring的标簽,像bean标簽那樣使用,我們先概覽一些整體的流程:

  1. 建立一個需要擴充的元件
  2. 定義一個XSD檔案,描述元件内容
  3. 建立一個java類,實作BeanDefinitionParser接口,用來解析XSD檔案中的定義群組件定義
  4. 建立一個Handler類,擴充

    NameSpaceHandlerSupport

    ,目的是将元件注冊到容器。
  5. 編寫(添加)

    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);
	}
	 
}