Spring——使用自定义标签

文章内容参考了《Spring源码深度解析》一书。自己照着书中内容做了一遍,不懂的地方以及采坑的地方会在文中记录。

推荐一篇post,关于Spring配置文件的命名空间:

https://www.cnblogs.com/gonjan-blog/p/6637106.html

我们暂时只是知道使用Spring的常规标签,加个bean,事务,Aop等等。随着满足业务的需求,同时降低程序员的工作量,我们有时需要自己定制一些标签。话补多少,下面进入主题。

自定义标签的使用

扩展Spring自定义标签大致需要如下几步:(把大象装冰箱,需要三步,开门,放,关门。。。)

1.创建需要扩展的组件

2.定义XSD文件描述组件内容

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

4.创建Handler文件,扩展字NamespaceHandlerSupport,目的是将组件注册到Spring容器

5.编写Spring.handlers和Spring.schemas文件

上述,五点看完了,我最开始时一头雾水,这是什么啊?别着急,跟哥往下走。下面有好东西,保证不打晕你。

例子:

1.创建POJO,接收配置文件

 1 package test.customtag;
 2
 3 public class User {
 4     private String userName;
 5     public String getUserName() {
 6         return userName;
 7     }
 8     public void setUserName(String userName) {
 9         this.userName = userName;
10     }
11     private String email;
12     public String getEmail() {
13         return email;
14     }
15     public void setEmail(String email) {
16         this.email = email;
17     }
18 }

2.定义一个XSD文件描述组件内容

src/main/resources/META-INF/user.xsd

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/schema/user" xmlns:tns="http://www.example.org/schema/user" elementFormDefault="qualified">
 3     <element name="user2">
 4         <complexType>
 5             <attribute name ="id" type = "string"/>
 6             <attribute name ="userName" type = "string"/>
 7             <attribute name ="email" type = "string"/>
 8         </complexType>
 9     </element>
10 </schema>

描述了一个targetNamespace,并且创建了一个element user2。里面有三个attribute。主要是为了验证Spring配置文件中的自定义格式。再进一步解释,就是,Spring位置文件中使用的user2自定义标签中,属性只能是上面的三种,有其他的属性的话,就会报错。

网上有人说element ,complexType等等这些标签要用XSD开头的标签,但是我这里没有用也能成功的执行,我猜测可能是spring的版本问题。(我这个猜测没有依据)

大家对这个XSD可能会有疑问,不要担心。推荐一篇post,里面讲解的很好,地址放在文章开头那里。

3.创建文件,实现BeanDefinitionParser接口,用来解析XSD文件中的定义和组件定义

 1 package test.customtag;
 2
 3
 4 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
 5 import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
 6 import org.springframework.util.StringUtils;
 7 import org.w3c.dom.Element;
 8
 9 public class UserBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
10
11     @SuppressWarnings("rawtypes")
12     protected Class getBeanClass(Element element) {
13         return User.class;
14     }
15
16     protected void doParse(Element element, BeanDefinitionBuilder bean) {
17         String userName = element.getAttribute("userName");
18         String email = element.getAttribute("email");
19         if (StringUtils.hasText(userName)) {
20             bean.addPropertyValue("userName", userName);
21         }
22         if (StringUtils.hasText(email)){
23             bean.addPropertyValue("email", email);
24         }
25
26     }
27 }

上文,虽说是继承了AbstractSingleBeanDefinitionParser ,但根本上来说,是实现了BeanDefinitionParser接口。

4.创建Handler文件,扩展自NamespaceHandlerSupport,目的是将组件注册到Spring容器中。

 1 package test.customtag;
 2
 3 import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
 4
 5 public class MyNamespaceHandler extends NamespaceHandlerSupport {
 6
 7     public void init() {
 8
 9         registerBeanDefinitionParser("user2", new UserBeanDefinitionParser());
10     }
11
12 }

5.编写Spring.handlers和Spring.schemas文件

路径:src/main/resources/META-INF/Spring.handlers

1 http\://www.example.org/schema/user=test.customtag.MyNamespaceHandler

路径:src/main/resources/META-INF/Spring.schemas

1 http\://www.example.org/schema/user.xsd=META-INF/user.xsd

\ 是转义字符的概念。

6.创建测试配置文件

路径:src/main/resources/test.xml

1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4     xmlns:myname2="http://www.example.org/schema/user"
5     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
6     http://www.example.org/schema/user http://www.example.org/schema/user.xsd">
7
8     <myname2:user2 id = "testbean" userName = "lee" email = "bbb"/>
9 </beans>

在第4行这里引入了myname2对应的命名空间,它会到第六行(http://www.example.org/schema/user.xsd)找到对应XSD文件进行check。第六行的user.xsd文件的位置,到步骤5里的Spring.schemas里去参照。

在这里说明一下自己遇到的疑问:第八行,自己eclipse报了红叉,信息如下:

Multiple annotations found at this line:
    - cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element ‘myname2:user2‘.
    - schema_reference.4: Failed to read schema document ‘http://www.example.org/schema/user.xsd‘, because 1) could not find the
     document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.

但是,我没有解决它,直接执行第6步的代码,最后成功执行了,搞不懂原因。

6.测试。

 1 package test.customtag;
 2
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5
 6 public class Tst {
 7     public static void main(String[] args) {
 8         ApplicationContext beans=new ClassPathXmlApplicationContext("classpath:test.xml");
 9         User user=(User)beans.getBean("testbean");
10         System.out.println("username:"+user.getUserName()+"  "+"email:"+user.getEmail());
11     }
12 }   

文章记录的不是特别的详细,有一些知识点没有全面的记录。但是,跟着一步步做,Spring自定义标签的实现,应该是没有问题了。稍后,有时间,会记录Sping源码中,关于自定义标签解析的部分。与君共勉。

原文地址:https://www.cnblogs.com/lihao007/p/8455916.html

时间: 2024-10-15 17:30:58

Spring——使用自定义标签的相关文章

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

1. XML Schema 1.1 最简单的标签 一个最简单的标签,形式如: <bf:head-routing key="1" value="1" to="test2"/> 该标签只包含了若干属性,我们就在xsd文件中这么定义 <!-- 声明一个标签,名字为head-routing,他的类型为headRouting--> <xsd:element name="head-routing" type=

Spring的自定义标签

当Spring拿到一个元素时首先要做的是根据命名空间进行解析,如果是默认的命名空间,则使用parseDefaultElement方法进行元素解析,否则使用parseCustom Element方法进行解析. protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { if (delegate.isDefaultNamespace(root)) { NodeList nl =

Spring MVC 自定义标签如何使用@Autowired自动装配注解

在用Spring MVC框架做Web应用开发中,在一些特殊请款下我们都会用自定标签来完成一些特殊的功能. 在通常情况下,自定义标签的内容如果不通过访问服务就能实现,那么继承TagSupport,重写doStartTag()方法就可以实现基本功能. eg. 实现一个html标记的反转义功能的自定义标签 /** * @Comment * @Author Ron * @date 2016年8月30日 上午9:02:56 */ public class HtmlUnEncodeTags extends

Spring 源码分析(四)--自定义标签的使用

在之前的代码分析中,Spring标签的解析分为 默认标签和自定义标签两种,前一篇文章分析了Spring中对默认标签的解析过程. 本文将分析Spring中自定义标签的使用过程: 一:回顾 public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader { /** * Parse the elements at the root level in the document: * "imp

dubbo源码学习(二) : spring 自定义标签

做dubbo的配置时很容易发现,dubbo有一套自己的标签,提供给开发者配置,其实每一个标签对应着一个 实体,在容器启动的时候,dubbo会对所有的配置进行解析然后将解析后的内容设置到实体里,最终dubbo会根据实体中的值生成贯穿全局的统一URL.利用自定义标签使配置简单明了化,与spring完美融合.下面自己写一个自定义标签,主要需要如下 几个步骤: 1.编写实体类2.编写Parser解析类3.编写NameSpaceHandle类4.配置spring.handlers5.配置spring.sc

Spring 自定义标签配置

前景:经常使用一些依赖于Spring的组件时,发现可以通过自定义配置Spring的标签来实现插件的注入,例如数据库源的配置,Mybatis的配置等.那么这些Spring标签是如何自定义配置的?学习Spring标签的自定义配置为以后实现分布式服务框架做技术储备. 技术分析:Spring的标签配置是通过XML来实现的,通过XSD(xml Schema Definition)来定义元素,属性,数据类型等. Spring自定义标签解析 1.Spring启动时通过扫描根目录下的META-INF文件下的sp

Spring自定义标签

一.原理: 1.Spring通过XML解析程序将其解析为DOM树, 2.通过NamespaceHandler指定对应的Namespace的BeanDefinitionParser将其转换成BeanDefinition. 3.再通过Spring自身的功能对BeanDefinition实例化对象. 二.自定义标签步骤 1.定义三个文件 META-INF/spring.handlers http\://www.newlandframework.com/dubbo=com.newlandframewor

spring 自定义标签 学习

自定义配置文件到spring 中,有时候想做一些数据结构的配置化信息,根据业务做一个扩展. 首先: 在项目的META-INF目录下新建两个文件spring.handlers,和spring.shcemas Spring.handlers在类org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver中已经写死了要取mapping的handlerMappingsLocation的路径 public static fina

spring源码研究2 自定义标签实现及使用

1.自定义标签实现及使用参考: http://blog.csdn.net/fighterandknight/article/details/50112701 1)创建一个需要扩展的组件 User.java 2)定义一个XSD文件,描述组件内容 user.xsd 3)创建一个java类 MyParser.java ,实现BeanDefinitionParser接口,用来解析XSD文件中的定义和组件定义 4)创建一个Handler类 MyNamespaceHandler.java ,扩展子NameS