Spring源码学习(3)—— 自定义标签
上一篇讲了Spring对默认标签的解析,Spring提供了很多属性,可以供开发者根据不同情况使用。绝大多数情况下,这些功能就已经足够了。但是,当用户有更特殊的需求,又或者很多公司自己实现的服务治理框架有一些自定义的需求是spring默认属性无法提供,或者是有更好得实现方式时,一种方式是像Spring一样用原生态的方式去解析定义好的XML文件,然后转化为配置对象,但这样实现起来比较复杂,还有一种方式就是通过Spring提供的可扩展Schema的支持,扩展自定义标签。
扩展自定义标签大致需要以下几个步骤:
1、创建一个需要扩展的组件
2、定义一个.xsd文件描述组件的内容
3、创建一个文件实现BeanDefinitionParser接口,用来解析xsd文件中的定义和组件的含义
4、创建一个handle文件,实现NamespaceHandleSupport,将组件和解析类注册到spring中
5、编写spring.handlers和spring.schemas
首先我们创建一个简单的pojo
package com.wuzhe.spring.test; public class User {
private String userName; public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
}
}
第二步,新建一个xsd文件描述自定义的标签
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
xmlns="http://www.test.com/user"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
targetNamespace="http://www.test.com/user"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans" />
<xsd:element name="user">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<xsd:attribute name="userName" type="xsd:string" />
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
</xsd:schema>
这里定义了一个新的命名空间targetNamespace:http://www.test.com/user 并定义了自定义标签user的属性等信息。
接下来就需要定义解析自定义标签,将其转化为beanDefinition了。spring通过实现BeanDefinitionParser接口来解析自定义标签。
package com.wuzhe.spring.test; import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
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 bean){
String userName = element.getAttribute("userName");
bean.addPropertyValue("userName", userName);
}
}
这里只是简单地将自定义标签user中的userName属性,通过set注入到bean中。所以在beanDefinition添加了对应的PropertValue。
定义好了解析标签的过程,接下来就要在spring中注册这个标签和解析器的联系,这样spring在解析对应自定义标签时就知道用哪个解析器去解析它。
spring中通过扩展NamespaceHandlerSupport来实现这一功能。
package com.wuzhe.spring.test; import org.springframework.beans.factory.xml.NamespaceHandlerSupport; public class Handler extends NamespaceHandlerSupport {
public void init() {
registerBeanDefinitionParser("user", new UserBeanDefinitionParser());
}
}
最后我们需要编写spring.handlers和spring.schemas这两个文件。这两个文件的功能是在解析xml文件时,一旦遇到自定义标签,就会通过这两个文件找到对应的xsd文件和对应的Handler,然后在handler中注册的对应标签和解析器来解析自定义标签。
这两个文件的默认位置是在resource下的META-INF文件夹下
spring.handlers
http\://www.test.com/user=com.wuzhe.spring.test.Handler
spring.schemas
http\://www.test.com/user.xsd=META-INF/user.xsd
这里http后的\实际上是为了转义冒号的。另外需要特别注意xsd文件和handler类的路径一定不能错。
到这里自定义标签的准备工作就已经完成了。我们可以写一个测试demo
首先容器的配置文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cutesource="http://www.test.com/user"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.test.com/user http://www.test.com/user.xsd">
<cutesource:user id="testUser" userName="haha"/>
</beans>
这里使用了自定义的标签user,设置了属性userName的值
写个测试类
public class Main {
public static void main(String[] args) {
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("user.xml"));
User user = (User) beanFactory.getBean("testUser");
System.out.println(user.getUserName());
}
}
我们发现通过自定义标签的方式,成功获取了user实例,并且这个实例的userName属性被设置为了haha。说明我们的自定义配置生效了。
Spring源码学习(3)—— 自定义标签的更多相关文章
- Spring 源码学习(1) —— 自定义标签
Spring 工作流程是先加载解析xml配置文件:配置文件中存在默认的标签,也可以自定义标签.解析默认标签调用: private void parseDefaultElement(Element el ...
- spring源码学习之默认标签的解析(一)
继续spring源码的学习之路,现在越来越觉得这个真的很枯燥的,而且我觉得要是自己来看源码,真的看不下去,不是没有耐心,而是真的没有头绪,我觉得结合着书来看,还是很有必要的,最起码大致的流程是能够捋清 ...
- spring源码学习之默认标签的解析(二)
这个是接着上一篇来写,主要是这章内容比较多,还是分开来写吧! 一.AbstractBeanDefinition属性介绍 XML中的所有的属性都可以在GenericBeanDefinition中找到对应 ...
- spring源码研究2 自定义标签实现及使用
1.自定义标签实现及使用参考: http://blog.csdn.net/fighterandknight/article/details/50112701 1)创建一个需要扩展的组件 User.ja ...
- Spring源码学习-容器BeanFactory(四) BeanDefinition的创建-自定义标签的解析.md
写在前面 上文Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签对Spring默认标签的解析做了详解,在xml元素的解析中,Spri ...
- Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签
写在前面 上文Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作中Spring对XML解析后创建了对应的Docum ...
- Spring源码学习
Spring源码学习--ClassPathXmlApplicationContext(一) spring源码学习--FileSystemXmlApplicationContext(二) spring源 ...
- Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作
写在前面 上文 Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件主要讲Spring容器创建时通过XmlBeanDefinitionReader读 ...
- Spring源码学习笔记12——总结篇,IOC,Bean的生命周期,三大扩展点
Spring源码学习笔记12--总结篇,IOC,Bean的生命周期,三大扩展点 参考了Spring 官网文档 https://docs.spring.io/spring-framework/docs/ ...
- spring源码学习之路---IOC初探(二)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章当中我没有提及具体的搭 ...
随机推荐
- python从字符串中提取指定的内容
有如下字符串: text=cssPath:"http://imgcache.qq.com/ptlogin/v4/style/32",sig:"OvL7F1OQEojtPk ...
- docker之Dockerfile实践
上一篇介绍了Dockerfile中使用的指令,现在开始进行指令实践 先查看下本地的镜像,选一个作为base image: [root@docker ~]# docker images REPOSITO ...
- java基础hashmap
Iterator中hasNext(), next() 在Iterator类中,我们经常用到两个方法: hasNext(), next(),具体含义: next(), 是返回当前元素, 并指向下一个元 ...
- Pandas之索引
Pandas的标签处理需要分成多种情况来处理,Series和DataFrame根据标签索引数据的操作方法是不同的,单列索引和双列索引的操作方法也是不同的. 单列索引 In [2]: import pa ...
- Lintcode376-Binary Tree Path Sum-Easy
376. Binary Tree Path Sum Given a binary tree, find all paths that sum of the nodes in the path equa ...
- datetime字符串中含T
json序列化datetime类型,返回给前端进行展示,字符串带T 例如:var time = 2018-08-08T09:07:04.767 => time.substr(0, 16).r ...
- U3D外包公司—北京动点(公司性质)承接U3D、Kinect、VR虚拟现实,增强现实,体感互动,大屏互动等各类外包
unity3d外包就找动点软件承接虚拟现实项目外包 承接U3D.Kinect.VR虚拟现实,增强现实,体感互动,大屏互动等各类外包 联系请加QQ:372900288 联系电话:13911652504 ...
- 要想成为前端大神,那些你不得不知晓的web前端命名规范。
一.Web语义化 1.1 H5的语义化 对于经验资深的前端er,在给web布局时,相信都会很注重标签和命名的规范.尤其是随着html5的普及发展,更是把web前端语义化推向一个新的台阶上.比如html ...
- vue--音乐播放器
github: https://github.com/vinieo/vue-music 效果: 基础组件: 1.confirm:确认对话框组件 2.listview:通讯录列表组件 3.loading ...
- CSS之user-select——设置标签中的文字是否可被复制
详细介绍请参考 http://www.css88.com/book/css/properties/user-interface/user-select.htm CSS样式 user-select:no ...