基于Spring 自定义标签实现_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 基于Spring 自定义标签实现

基于Spring 自定义标签实现

 2017/11/30 13:04:37  jiandequn  程序员俱乐部  我要评论(0)
  • 摘要:一、源码分析:Spring标签的定义分为默认标签和自定义标签Spring源代码:[DefaultBeanDefinitionDocumentReader.java]/***Parsetheelementsattherootlevelinthedocument:*"import","alias","bean".*@paramroottheDOMrootelementofthedocument*/protectedvoidparseBeanDefinitions(Elementroot
  • 标签:实现 Spring 自定义
一、源码分析:
  Spring标签的定义分为默认标签和自定义标签
  Spring源代码:[DefaultBeanDefinitionDocumentReader.java]
class="java">
/**
	 * Parse the elements at the root level in the document:
	 * "import", "alias", "bean".
	 * @param root the DOM root element of the document
	 */
	protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
		//对beans的处理
		if (delegate.isDefaultNamespace(root)) {
			NodeList nl = root.getChildNodes();
			for (int i = 0; i < nl.getLength(); i++) {
				Node node = nl.item(i);
				if (node instanceof Element) {
					Element ele = (Element) node;
					if (delegate.isDefaultNamespace(ele)) {
						//对默认标签处理
						parseDefaultElement(ele, delegate);
					}
					else {            //对自定义标签处理
						delegate.parseCustomElement(ele);
					}
				}
			}
		}
		else { //对自定义标签处理
			delegate.parseCustomElement(root);
		}
	}

Spring其他集成组件如SpringMVC使用了自定义标签。
二、实现自定义标签
   步骤:
    1、创建一个需要扩展的组件。
       如:定义一个User来接受xml文件信息
        
package ppfuns;

/**
 * Created with IntelliJ IDEA.
 * User: **
 * Date: 2017/11/22
 * Time: 10:09
 * To change this template use File | Settings | File Templates.
 */
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文件描述主键内容。
         如创建了一个user.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="userName" type="string"/>
            <attribute name="email" type="string"/>
        </complexType>
    </element>
</schema>

    3、创建一个文件、实现BeanDefinitionParser接口,用来解析XSD文件中的定义和组件定义
     
package ppfuns.parser;

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

/**
 * Created with IntelliJ IDEA.
 * User: 简德群
 * Date: 2017/11/22
 * Time: 10:22
 * To change this template use File | Settings | File Templates.
 */
public class UserBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
    /**
     * Element 对应的元素User
     * @param element
     * @return
     */
    protected Class getBeanClass(Element element){
        return User.class;
    }

    /**
     * 从element元素中提取对应元素的值
     * @param element
     * @param builder
     */
    @Override
    protected void doParse(Element element, BeanDefinitionBuilder builder) {
        String username = element.getAttribute("name");
        String email = element.getAttribute("email");
        if(StringUtils.hasText(username)){
            builder.addPropertyValue("name",username);
        }
        if(StringUtils.hasText(email)){
            builder.addPropertyValue("email",email);
        }
    }
}
 

    4、创建一个handler文件,扩展自NamespaceHandlerSupport,目的是将组件注册到Spring容器中
package ppfuns.parser;

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

/**
 * Created with IntelliJ IDEA.
 * User: 简德群
 * Date: 2017/11/22
 * Time: 10:22
 * To change this template use File | Settings | File Templates.
 */
public class UserBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
    /**
     * Element 对应的元素User
     * @param element
     * @return
     */
    protected Class getBeanClass(Element element){
        return User.class;
    }

    /**
     * 从element元素中提取对应元素的值
     * @param element
     * @param builder
     */
    @Override
    protected void doParse(Element element, BeanDefinitionBuilder builder) {
        String username = element.getAttribute("name");
        String email = element.getAttribute("email");
        if(StringUtils.hasText(username)){
            builder.addPropertyValue("name",username);
        }
        if(StringUtils.hasText(email)){
            builder.addPropertyValue("email",email);
        }
    }
}


    5、编写spring.handlers和Spring.schemas文件。这两个文件需放在resources/META-INF下
       spring.handlers文件:指定NamespaceHander位置
      
http\://www.lexueba.com/schema/user=ppfuns.parser.MyNameSpaceHandler

       spring.schemas文件:指定xsd文件映射位置
      
http\://www.lexueba.com/schema/user/user.xsd=user.xsd

   上面已经完成了对自定义标签的实现,那接下来就测试一下咯
    spring-user.xml文件定义
   
<?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-3.2.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.2.xsd
       http://www.lexueba.com/schema/user
	   http://www.lexueba.com/schema/user/user.xsd"
	   >

	 <myName:user id="userBean" userName="jiandequn" email="9780307441@qq.com" ></myName:user>
</beans>

    Test运行代码:
    
package ppfuns.junit;

import junit.framework.Assert;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import ppfuns.lookup.TestAbstractLookupMethod;
import ppfuns.replaceMethod.ReplacedMethodTest;

/**
 * Created with IntelliJ IDEA.
 * User: 简德群
 * Date: 2017/11/27
 * Time: 9:56
 * To change this template use File | Settings | File Templates.
 */
public class JunitTest {
  
    @Test
    public void test(){
        BeanFactory bf = new  XmlBeanFactory(new ClassPathResource("spring-user.xml"));
        ppfuns.User t1 = (ppfuns.User) bf.getBean("userBean");
        Assert.assertSame(t1,t1);
        System.out.println(t1.getUsername()+","+t1.getEmail());
    }
}

     

  说明:如想了解具体实现看《Spring源码深度解析》的第4章节
发表评论
用户名: 匿名