`

基于Spring 自定义标签实现

    博客分类:
  • java
阅读更多
一、源码分析:
  Spring标签的定义分为默认标签和自定义标签
  Spring源代码:[DefaultBeanDefinitionDocumentReader.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章节
分享到:
评论

相关推荐

    spring自定义标签例子

    在"spring自定义标签例子"这个项目中,我们可以深入理解这一特性,特别是通过Chapter2工程的实例来学习。 Spring框架的自定义标签通常用于简化XML配置,提升可读性和可维护性。这些标签是基于Java的`org.spring...

    spring mvc freemarker 自定义标签

    下面将详细介绍Spring MVC与Freemarker自定义标签的使用。 首先,我们需要了解Freemarker的基础。Freemarker是一个基于模板的语言,它的主要任务是根据数据模型生成输出。在Spring MVC中,Freemarker模板通常用于...

    06 源码分析-spring自定义标签解析过程

    本节将深入探讨Spring 5.2.9版本中自定义标签的解析机制,以及背后的源码实现。 首先,Spring XML配置文件中的自定义标签是由Spring的`BeanDefinitionParser`接口处理的。这个接口定义了`parse()`方法,用于解析...

    基于Spring开发之自定义标签及其解析

    基于Spring开发之自定义标签及其解析 Spring框架是现在Java最流行的开源框架之一,需要实现一些自定义的标签,主要是方便使用我们框架的人能够快速、简单进行配置。自定义标签的实现离不开XML Schema的定义,我们...

    spring security进级篇 V 自定义标签控制显示

    这篇"Spring Security进阶篇 V 自定义标签控制显示"的博客文章显然深入探讨了如何在Spring Security中实现自定义的安全控制,以便更好地管理和展示应用内容。在本文中,我们将详细解析这个主题,并与"JSP自定义标签...

    Spring自定义配置文件便签[Maven]工程可运行

    这个名为"Spring自定义配置文件便签[Maven]工程可运行"的项目,显然是一个基于Maven构建的Spring 5.0应用程序,它包含了自定义配置文件和标签的实现。让我们深入探讨一下这些概念及其在实际应用中的作用。 首先,...

    实现通过jfinal框架自动扫描freemarker的自定义标签.zip

    在Java Web开发中,JFinal和FreeMarker是两个非常重要的工具。JFinal是一个基于Java的高效、极简的Web开发框架,而FreeMarker...在开发过程中,你还可以结合Spring等依赖注入框架,进一步优化自定义标签的管理和使用。

    Struts2、Spring、Freemarker自定义标签

    在Struts2中,可以通过实现`com.opensymphony.xwork2.util.ValueStackAware`接口创建自定义标签,让标签能够访问值栈中的数据。Spring框架也有自己的标签库,如Spring Taglib,可以简化JSP页面中的Spring Bean引用。...

    spring3标签库

    这两个主要的TLD(Tag Library Descriptor)文件——`spring-form.tld`和`spring.tld`,提供了丰富的自定义标签,帮助开发者更高效、更直观地处理数据绑定、表单渲染以及模型对象的操作。 首先,让我们深入了解一下...

    自定义分页标签struts2,spring

    本项目"自定义分页标签struts2,spring"是针对Struts2和Spring框架的一个自定义标签实现,旨在简化开发过程,提高代码的可复用性和可维护性。下面我们将详细探讨这个项目中的关键技术点。 首先,Struts2是一个非常...

    jsp自定义标签实例

    首先,JSP自定义标签的工作原理是基于TLD(Tag Library Descriptor)文件,它定义了自定义标签的元数据,如标签名称、属性、返回类型等。在编写自定义标签时,我们需要创建一个Java类来处理标签逻辑,这个类通常会...

    分页工具条自定义标签

    `PageTag.java`文件很可能就是一个自定义标签类,用于实现分页工具条的功能。 在`PageTag.java`中,我们可能会看到以下关键部分: 1. **标签解析**:这个类会实现`javax.servlet.jsp.tagext.Tag`接口或者其子接口...

    基于spring的sql map实现

    MyBatis的动态SQL可以通过`&lt;if&gt;`, `&lt;choose&gt;`, `&lt;when&gt;`, `&lt;otherwise&gt;`, `&lt;where&gt;`, `&lt;set&gt;`, 和 `&lt;foreach&gt;`等标签实现。例如,假设我们有一个用户列表查询,根据用户状态过滤: ```xml SELECT * FROM users ...

    spring中自定义注解(annotation)与AOP中获取注解

    在Spring中,自定义注解通常用于简化配置、实现依赖注入、标记特定行为等。要创建一个自定义注解,我们需要定义一个注解类型,并指定它的属性。例如: ```java @Retention(RetentionPolicy.RUNTIME) @Target...

    下拉框自定义标签

    在实际项目中,除了Struts2,还有其他框架如Spring MVC、JSF等也支持自定义标签。总的来说,理解和掌握自定义标签的创建和使用是提高开发效率、提升代码质量的重要手段,对于提升IT专业技能有着积极的作用。

    基于Spring+JMX+Tomcat实现资源动态管理

    标题"基于Spring+JMX+Tomcat实现资源动态管理"揭示了我们将讨论的核心技术栈。 首先,Spring是一个广泛使用的Java应用开发框架,它提供了依赖注入(DI)和面向切面编程(AOP)等功能,极大地简化了企业级应用的构建...

    基于Spring MVC的web框架 1.1.11

    工具类数据校验 jsp自定义标签 Spring自定义注解 默认requestMapping 1.1.2 代码生成器 1.1.3 首页修改 dateformat.js 时间参数转换 SpringMVC配置文件集中 快递参数接口 1.1.4 des加解密字符串和文件 1.1.5 redis...

    SSH框架整合通用模板(内涵自定义标签分页)

    4. **自定义标签分页**:在SSH框架中,自定义标签通常用于处理视图层的复杂逻辑,比如数据的分页显示。开发者可以创建一个自定义标签,接收参数如当前页、每页条数等,然后在后台计算总页数,查询相应范围的数据,...

    Java开发框架spring实现自定义缓存标签

    本文将详细介绍如何在Spring中实现自定义缓存标签。 首先,自定义缓存标签通常是为了满足特定的业务需求或扩展Spring默认缓存功能。例如,`@MyCacheable`就是一个自定义的缓存注解,用于标记需要缓存的方法。在定义...

Global site tag (gtag.js) - Google Analytics