Spring自定义标签
一、标签解析原理:
1、Spring通过XML解析程序将其解析为DOM树,
2、通过NamespaceHandler指定对应的Namespace的BeanDefinitionParser将其转换成BeanDefinition。
3、再通过Spring自身的功能对BeanDefinition实例化对象。
二、自定义标签步骤
1、定义三个文件
META-INF/soring.handlers 指定命名空间解析实现类
META-INF/spring.schemas 指定命名空间文件
META-INF/xxx.xsd 定义命名空间
2、实现NameSpace(命名空间)解析类(继承NamespaceHandlerSupport)
3、配置相应element元素的Parser(实现BeanDefinitionParser接口)和Bean(例如实现InitializingBean, DisposableBean,ApplicationContextAware, ApplicationListener,要看配置在element需要哪些属性)
三、应用案例
以dubbo框架为例,可以看到:
1、3个属性文件
META-INF/spring.handlers
http\://www.newlandframework.com/dubbo=com.newlandframework.rpc.spring.DubboNamespaceHandler
META-INF/spring.schemas
http\://www.newlandframework.com/dubbo/dubbo.xsd=META-INF/dubbo.xsd
dubbo.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://www.newlandframework.com/dubbo"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
targetNamespace="http://www.newlandframework.com/dubbo"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans"/>
<xsd:element name="service">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<xsd:attribute name="interfaceName" type="xsd:string" use="required"/>
<xsd:attribute name="ref" type="xsd:string" use="required"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="registry">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<xsd:attribute name="ipAddr" type="xsd:string" use="required"/>
<xsd:attribute name="protocol" type="xsd:string" use="required"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="reference">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<xsd:attribute name="interfaceName" type="xsd:string" use="required"/>
<xsd:attribute name="ipAddr" type="xsd:string" use="required"/>
<xsd:attribute name="protocol" type="xsd:string" use="required"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
</xsd:schema>
2、Handler解析类
DubboNamespaceHandler
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.dubbo.config.spring.schema; import com.alibaba.dubbo.common.Version;
import com.alibaba.dubbo.config.*;
import com.alibaba.dubbo.config.spring.AnnotationBean;
import com.alibaba.dubbo.config.spring.ReferenceBean;
import com.alibaba.dubbo.config.spring.ServiceBean;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport; /**
* DubboNamespaceHandler
*
* @export
*/
public class DubboNamespaceHandler extends NamespaceHandlerSupport { static {
Version.checkDuplicate(DubboNamespaceHandler.class);
} public void init() {
registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true));
} }
3、定义parser解析bean文件
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.dubbo.config.spring.schema; import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.ExtensionLoader;
import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.alibaba.dubbo.common.utils.ReflectUtils;
import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.dubbo.config.*;
import com.alibaba.dubbo.config.spring.ReferenceBean;
import com.alibaba.dubbo.config.spring.ServiceBean;
import com.alibaba.dubbo.rpc.Protocol;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.config.TypedStringValue;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern; /**
* AbstractBeanDefinitionParser
*
* @export
*/
public class DubboBeanDefinitionParser implements BeanDefinitionParser { private static final Logger logger = LoggerFactory.getLogger(DubboBeanDefinitionParser.class);
private static final Pattern GROUP_AND_VERION = Pattern.compile("^[\\-.0-9_a-zA-Z]+(\\:[\\-.0-9_a-zA-Z]+)?$");
private final Class<?> beanClass;
private final boolean required; public DubboBeanDefinitionParser(Class<?> beanClass, boolean required) {
this.beanClass = beanClass;
this.required = required;
} ......
}
Spring自定义标签的更多相关文章
- spring基础---->spring自定义标签(一)
Spring具有一个基于架构的扩展机制,可以使用xml文件定义和配置bean.本博客将介绍如何编写自定义XML bean的解析器,并用实例来加以说明.其实我一直相信 等你出现的时候我就知道是你. Sp ...
- spring自定义标签之 自我实现
引言: 最近心情比较难以平静,周末的两天就跑出去散心了,西湖边上走走,看日落,还是不错的.回来博客上发现,在自定义标签上,最后一步实现忘记加上了.其实,人生的路程中,我们总是实现着自我的价值,让自己 ...
- spring自定义标签之 规范定义XSD
引言: spring的配置文件中,一切的标签都是spring定义好的.<bean/>等等,有了定义的规范,才能让用户填写的正常可用.想写自定义标签,但首先需要了解XML Schema De ...
- Spring 自定义标签配置
前景:经常使用一些依赖于Spring的组件时,发现可以通过自定义配置Spring的标签来实现插件的注入,例如数据库源的配置,Mybatis的配置等.那么这些Spring标签是如何自定义配置的?学习Sp ...
- 自己构建一个Spring自定义标签以及原理讲解
平时不论是在Spring配置文件中引入其他中间件(比如dubbo),还是使用切面时,都会用到自定义标签.那么配置文件中的自定义标签是如何发挥作用的,或者说程序是如何通过你添加的自定义标签实现相应的功能 ...
- spring 自定义标签的实现
在我们进行Spring 框架开发中,估计用到最多的就是bean 标签吧,其实在Spring中像<mvc/><context/>这类标签以及在dubbo配置的标签都是属于自定义的 ...
- Spring自定义标签解析与实现
在Spring Bean注册解析(一)和Spring Bean注册解析(二)中我们讲到,Spring在解析xml文件中的标签的时候会区分当前的标签是四种基本标签(import.alias ...
- spring自定义标签学习
看到几篇很全的自定义标签,从定义到使用,写的很好. 这里我也是在那里学习的,对学习spring源码也很有帮助. 贴出来与大家共享. http://sammor.iteye.com/blog/11009 ...
- Spring自定义标签的实现
首先 简单写下 spring xml解析的过程 通过一段简单的 调用spring代码开始 public static void main(String[] args) { ApplicationCon ...
随机推荐
- java 对象的上转型对象(父类)
Example5_10.java class 类人猿 { void crySpeak(String s) { System.out.println(s); } } class People exten ...
- CodeForces 682C Alyona and the Tree(广搜 + 技巧)
方法:从根节点开始广搜,如果遇到了应该删除的点,就再广搜删掉它的子树并标记,然后统计一下被标记的个数就是答案,所谓技巧就是从根节点开始搜索的时候,如果遇到了某个节点的距离<0,就让它是0,0可以 ...
- CodeForces 190D Non-Secret Cypher
双指针. #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> ...
- linux下执行scrapy的爬虫定时任务
刚开始执行scrapy crawl zentaos可以完成扫描 但是通过linux的crontab任务,只执行了连接mongodb的操作,并创建了索引 也就是说scrapy crawl zentaos ...
- JavaScript 小技巧汇总
判断一个变量是否申明 if (typeof v === "undefined") { // ... } 判断一个变量是否是函数 function f() {} typeof f / ...
- 阅读android项目源码
版权声明:欢迎转载,转载请注明出处;http://blog.csdn.net/angcyo 上一篇,我们成功导入并运行了 贝壳单词 项目. 这篇文章, 带大家一起读一读源码. 打开 贝壳单词 项目,定 ...
- elasticsearch 管理工具
------------------sense------------------- google chrome 浏览器插件,数据交互使用 -------------------------hea ...
- DataBinding注意事项Error parsing XML: duplicate attribute以及如何在listview中使用DataBinding
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...
- 【第k小素数 】 打表问题
Prime Number TimeLimit: 1 Second MemoryLimit: 32 Megabyte Totalsubmit: 399 Accepted: 88 Description ...
- java.lang.RuntimeException: java.lang.NoSuchMethodException:
[java] 15/12/19 14:09:46 INFO mapred.JobClient: Task Id : attempt_201512182036_0017_m_000000_0, Stat ...