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

猜你喜欢

转载自blog.csdn.net/saienenen/article/details/112913461