自己构建一个Spring自定义标签以及原理讲解
平时不论是在Spring配置文件中引入其他中间件(比如dubbo),还是使用切面时,都会用到自定义标签。那么配置文件中的自定义标签是如何发挥作用的,或者说程序是如何通过你添加的自定义标签实现相应的功能的呢?且看下文。
通过对本文的阅读,你会在阅读涉及到自定义标签的源码功能时事半功倍,而且还可以自己动手做出一个自己的自定义标签。
先呈上我自己在本地实现自定义标签的代码及对应讲解:
1、先无脑输出一个测试要用到的Bean类
public class User {
private String userName;
private String emailAddress;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
}
2、spring的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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:myname="http://www.zzq.com/schema/user"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.zzq.com/schema/user http://www.zzq.com/schema/user.xsd"> <aop:aspectj-autoproxy proxy-target-class="true"/>
<mvc:annotation-driven/>
<context:component-scan base-package="myDemoHome"/>
<context:property-placeholder location="classpath:properties/config.properties" ignore-unresolvable="true"/> <myname:myPw id="testUserBean" userName="zzq" emailAddress="zzqing@110.com"/> </beans>
3、从2中可以看到,命名空间中我添加了自定义的xmlns:myname="http://www.zzq.com/schema/user",以及http://www.zzq.com/schema/user跟http://www.zzq.com/schema/user.xsd。
其中紧跟xmlns冒号后面的部分,就是我们自定义标签引号前的部分,比如此处定义了myname,那么自定义标签中我就可以<myname:XXX/>这样引用了,其中的XXX则是在命名空间中定义的myPw。
中间http://www.zzq.com/schema/user对应此自定义标签的handler,放在Spring.handlers中。
最后的http://www.zzq.com/schema/user.xsd则定义了此自定义标签的XXX,即自定义标签冒号后面有什么,由此xsd定义,放在Spring.schemas中。
Spring.handlers跟Spring.schemas文件都放在META-INF目录下,因为spring会默认去此目录下读。
Spring.handlers如下所示:
http\://www.zzq.com/schema/user=myDemoHome.springElement.bdParser.UserNamespaceHandler
Spring.schemas如下所示:
http\://www.zzq.com/schema/user.xsd=META-INF/spring-test.xsd
3.1 自定义标签的解析类UserNamespaceHandler构建
package myDemoHome.springElement.bdParser; import myDemoHome.springElement.User;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element; public class UserBeanDefinitionParser extends AbstractSingleBeanDefinitionParser { @Override
protected Class getBeanClass(Element element) {
return User.class;
} @Override
protected void doParse(Element element, BeanDefinitionBuilder builder) {
String name = element.getAttribute("userName");
String address = element.getAttribute("emailAddress"); if (StringUtils.hasText(name)) {
builder.addPropertyValue("userName", name);
}
if (StringUtils.hasText(address)) {
builder.addPropertyValue("emailAddress", address);
}
} }
就是对element中的标签进行解析处理,完成从xml中的标签属性向对象值的转化
3.2 自定义标签解析类的注册 UserNamespaceHandler
package myDemoHome.springElement.bdParser;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
public class UserNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
registerBeanDefinitionParser("myPw", new UserBeanDefinitionParser());
}
}
此处的意思就是当遇到myPw这个标签的时候,往spring容器中注入这个标签的解析类,以完成后续对标签属性的解析。看到此处,各位道友有没有想起AOP的自定义注解aspectj-autoproxy 的解析呢?其实套路都是一样的。
3.3 xsd文件spring-test.xsd的定义
<?xml version="1.0" encoding="UTF-8" ?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.zzq.com/schema/user"
elementFormDefault="qualified"> <element name="myPw">
<complexType>
<attribute name="id" type="string"/>
<attribute name="userName" type="string"/>
<attribute name="emailAddress" type="string"/>
</complexType>
</element>
</schema>
此文件规定了自定义注解的标签,以及对应的属性
4、测试类ElementTest
package myDemoHome.springElement; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class ElementTest {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath*:spring/spring-config.xml");
User user = (User)applicationContext.getBean("testUserBean");
System.out.println(user.getEmailAddress());
}
}
再附上一张所用类的位置关系图

至此大功告成,最后运行一下测试类:

功德圆满!
总结:
构建一个自定义标签的流程便是如此,相信如果后面再遇到自定义标签,按照此构建思路反向解析一下便也能顺藤摸瓜知晓它的来龙去脉。其实看一下之前我们用过的中间件,像dubbo,也是一样的套路,只是功能更繁杂。
dubbo的jar包如图所示:

也是用了这三个实现的标签引用。
写在最后:至此,19年金三银四找工作之途的总结(包括技术跟个人感悟,感兴趣的道友可以移步我的另几篇博文一探究竟)便告一段落。今年自从去年下半年的资本收缩后,行情确实相较以往差了一些(虽然贫道也才17年入行),但我个人的感觉
是行业整体回归理性,之前是经过三四个月培训班下来就月薪十几K而且都抢着招人,太不正常。话说回来,不管外界行情怎样,只要你喜欢做这一行,都要静下心来多学习多探究,才能在不断的积累中让自己更上一层。今年年初两次阿里的面试
经历也让自己对于自身能力有了更客观真实的认识,不管是从项目经历还是个人技术积累上,都差很多。目前贫道新公司所处的部门,对技术比较注重,且技术大佬不少,工作都很认真,正是"发粪涂墙"之际,内心充满激情。后面的博文目前打算
更多偏向微服务(因为目前公司的项目用的就是微服务架构)、并发编程(因为前段时间买了本并发编程实战)。技术积累不是一朝一夕,与各位道友共勉!
自己构建一个Spring自定义标签以及原理讲解的更多相关文章
- 这一次搞懂Spring自定义标签以及注解解析原理
前言 在上一篇文章中分析了Spring是如何解析默认标签的,并封装为BeanDefinition注册到缓存中,这一篇就来看看对于像context这种自定义标签是如何解析的.同时我们常用的注解如:@Se ...
- spring基础---->spring自定义标签(一)
Spring具有一个基于架构的扩展机制,可以使用xml文件定义和配置bean.本博客将介绍如何编写自定义XML bean的解析器,并用实例来加以说明.其实我一直相信 等你出现的时候我就知道是你. Sp ...
- spring自定义标签之 自我实现
引言: 最近心情比较难以平静,周末的两天就跑出去散心了,西湖边上走走,看日落,还是不错的.回来博客上发现,在自定义标签上,最后一步实现忘记加上了.其实,人生的路程中,我们总是实现着自我的价值,让自己 ...
- spring自定义标签之 规范定义XSD
引言: spring的配置文件中,一切的标签都是spring定义好的.<bean/>等等,有了定义的规范,才能让用户填写的正常可用.想写自定义标签,但首先需要了解XML Schema De ...
- java_自定义标签运行原理
一.自定义标签运行原理: 二.文字说明 1.IE->web服务器 2.Web服务器->jsp 3.遇到自定义标签,首先实例化标签所对应的标签处理器类 4.调用setPageContext方 ...
- Spring 自定义标签配置
前景:经常使用一些依赖于Spring的组件时,发现可以通过自定义配置Spring的标签来实现插件的注入,例如数据库源的配置,Mybatis的配置等.那么这些Spring标签是如何自定义配置的?学习Sp ...
- Spring自定义标签
一.原理: 1.Spring通过XML解析程序将其解析为DOM树, 2.通过NamespaceHandler指定对应的Namespace的BeanDefinitionParser将其转换成BeanDe ...
- spring 自定义标签的实现
在我们进行Spring 框架开发中,估计用到最多的就是bean 标签吧,其实在Spring中像<mvc/><context/>这类标签以及在dubbo配置的标签都是属于自定义的 ...
- Spring自定义标签解析与实现
在Spring Bean注册解析(一)和Spring Bean注册解析(二)中我们讲到,Spring在解析xml文件中的标签的时候会区分当前的标签是四种基本标签(import.alias ...
随机推荐
- Android Training
Building Apps with Content Sharing Simple Data --> Intent && ActionProvider 介绍如何让应用程序共享简单 ...
- Hive管理表,外部表及外部分区表的深入探讨
Hive管理表,也叫内部表.Hive控制着管理表的整个生命周期,默认情况下Hive管理表的数据存放在hive的主目录:/user/hive/warehouse/下,并且当我们删除一张表时,这张表的数据 ...
- Unity-批量修改Prefab上的属性
问题描述:今天发现工程中有些prefab上的脚本丢失了一些引用,本以为手动拖拽上去搞定,后来查看其它prefab,也有类似的问题,于是写了一个小工具,批量修改下. 上代码: [ExecuteInEdi ...
- Git使用的自我总结
一.Git安装后打开Git bash,第一次使用 1.Git账号信息配置 2.用命令git clone从远程库克隆 会在克隆的项目下有一个隐藏的.git目录,这个目录是Git来跟踪管理版本库的,没事千 ...
- mysql学习3
1.索引 索引是表的目录,在查找内容之前可以先在目录中查找索引位置,以此快速定位查询数据.对于索引, 会保存在额外的文件中. 作用: 约束 加速查找 1.1.建立索引 a.额外的文件保存特殊的数据结构 ...
- 用万能马甲免费看VIP电影
什么是:万能马甲? 它浏览器的一个扩展程序插件,安装后能看一些热门网址的VIP特权,免费观看付费电影等. 使用过程: 1. 访问网址:http://www.wndd123.com/ 点击免费看电影时提 ...
- for循环:用turtle画一颗五角星
import turtle # 设置初始位置 turtle.penup() turtle.left(90) turtle.fd(200) turtle.pendown() turtle.right(9 ...
- 什么是 ajax?----异步 javascript 和 xml
GET 用于请求服务器数据 POST 用于上传数据到服务器,或者修改服务器数据 ajax 异步通信,实现页面的局部刷新,按需获取数据,节约带宽,带来更好的用户体验 客户端与服务器在不必刷新浏览器的情况 ...
- R语言读入数据库的中英名词互译测试并计分脚本(考试用)
1. 分子生物学中英文.csv,输入文件,两列,以tab键分隔的txt文本,没有列名 2. 错误的名解.csv, 如果在测试中拼写错误,会写出到这个文件,可用这个容易犯错的名词进行新的测试 3. 注意 ...
- redis消息队列,tp5.0,高并发,抢购
redis处理抢购,并发,防止超卖,提速 1.商品队列(List列表),goods_list 控制并发,防止超卖 2.订单信息(Hash集合),order_info ...