Spring 自定义标签

扩展自定义标签步骤(前提要把 Spring Core 包加入项目):
  • 创建一个需要扩展的组件
  • 定义一个 XSD 文件描述组件内容
  • 创建一个文件,实现 BeanDefinitionParse 接口,用来解析 XSD 文件中的定义和组件定义
  • 创建一个 Handler 文件,扩展自 NamespaceHandlerSupport,目的是将组件注册到 Spring 容器
  • 编写 Spring.handlers 和 Spring.schemas 文件


(1) 我们首先创建一个 User 类:只是用来接收配置文件
package main.java.com.wenniuwuren.spring.customize.tag;

/**
 * 1. 创建一个需要扩展的组件
 * Created by hzzhuyibin on 2016/11/14.
 */
public class User {

private String userName;

 private String email;



 public String getUserName() {
return userName;
 }

public void setUserName(String userName) {
this.userName = userName;
 }

public String getEmail() {
return email;
 }

public void setEmail(String email) {
this.email = email;
 }
}


(2) 定义一个 XSD 文件描述组件内容:定义了一个新的 targetNamespace,并在这个空间中定义了一个 name 为 user 的 element,user 有 3个属性 id,userName,email。

customizeBeanTest.xml:
targetNamespace 是一个 xml 的 schema 中的概念,表示 user 属于 http://www.wenniuwuren.com/schema/user 这个命名空间。自定义标签命名空间都是自己定义的。在其他 xml 中引入自定义的命名空间,就能使用自定义标签了。
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.wenniuwuren.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) 创建一个文件,实现 BeanDefinitionParse 接口,用来解析 XSD 文件中的定义和组件定义。

UserBeanDefinitionParse
package main.java.com.wenniuwuren.spring.customize.tag;


import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;


/**
 * 3. 创建一个文件, 实现 AbstractSingleBeanDefinitionParser 接口,用来解析 XSD 文件中的定义和组件定义
 * Created by hzzhuyibin on 2016/11/14.
 */
public class UserBeanDefinitionParse extends AbstractSingleBeanDefinitionParser {

// Element 对应的类
 protected Class getBeanClass(Element element) {
return User.class;
 }

// 从 element 中解析并提取对应的元素
 protected void doParse(Element element, BeanDefinitionBuilder bean) {
String userName = element.getAttribute("userName");
 String email = element.getAttribute("email");

 // 将提取的数据放入到 BeanDefinitionBuilder 中,待到完成所有 bean 的解析后统一注册到 beanFactory 中
 if (StringUtils.hasText(userName)) {
bean.addPropertyValue("userName", userName);

 }

if (StringUtils.hasText(email))
bean.addPropertyValue("email", email);



 }

}

(4) 创建一个 Hanlder 文件,目的是将组件注册到 Spring 容器
遇到自定义标签 <user:aaa 这样类似于 user 开头的元素,就会把这个元素扔给对应的UserBeanDefinitionParse 去接信息
package main.java.com.wenniuwuren.spring.customize.tag;

import org.springframework.beans.factory.xml.NamespaceHandlerSupport;

/**
 * 4. 创建一个 Hanlder 文件,继承自 NamespaceHandlerSupport,目的是将组件注册到 Spring 容器
 *
 * 遇到自定义标签 <user:aaa 这样类似于 user 开头的元素,就会把这个元素扔给对应的UserBeanDefinitionParse 去接信息
 * Created by hzzhuyibin on 2016/11/14.
 */
public class MyNamespaceHandler extends NamespaceHandlerSupport{
@Override
 public void init() {
registerBeanDefinitionParser("user", new UserBeanDefinitionParse());
 }
}

(5) 编写 Spring.handlers 和 Spring.schemas 文件,默认在工程的 /META-INF/ 文件夹下,当然,也可以通过 Spring 的扩展或者修改源码的方式改变路径
spring.handlers :
http\://www.wenniuwuren.com/schema/user=main.java.com.wenniuwuren.spring.customize.tag.MyNamespaceHandler

spring.schemas: 
http\://www.wenniuwuren.com/schema/user.xsd=META-INF/customizeBeanTest.xml

到此,自定义配置就完成了。Spring 加载自定义标签大致流程是遇到自定义标签后,去 spring.handlers 和 spring.schemas 中去找对应的 handler 和 XSD,进而有找到对应的 handler 以及解析元素的 parse。


(6) 创建测试配置文件:在配置文件中引入对应的命名空间以及 XSD 后,就可以直接使用自定义标签了。
引用自定义标签 xsd: xsi:schemaLocation="http://www.wenniuwuren.com/schema/user http://www.wenniuwuren.com/schema/user.xsd"
定义使用自定义标签的命名空间 "http://www.wenniuwuren.com/schema/user"  和前缀 wenniuwuren : xmlns:wenniuwuren="http://www.wenniuwuren.com/schema/user"
<?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:wenniuwuren="http://www.wenniuwuren.com/schema/user"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.wenniuwuren.com/schema/user http://www.wenniuwuren.com/schema/user.xsd">

    <wenniuwuren:user id="testCustomizeBean" userName="aaa" email="[email protected]" />

</beans>

(7) 测试
package main.java.com.wenniuwuren.spring.customize.tag;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by hzzhuyibin on 2016/11/14.
 */
public class Test {

public static void main(String[] args) {
ApplicationContext bf = new ClassPathXmlApplicationContext("main/resources/testCustomizeBean.xml");
 User user = (User) bf.getBean("testCustomizeBean");
 System.out.println(user.getUserName() + ", " + user.getEmail());
 }
}

运行结果:


工程目录结构:

猜你喜欢

转载自blog.csdn.net/wenniuwuren/article/details/53171670