小编给大家分享一下Spring自定义XML schema 扩展的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
Spring
整合dubbo
的事例
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <dubbo:application name="demo-provider"/> <dubbo:registry address="zookeeper://127.0.0.1:2181"/> <dubbo:protocol name="dubbo" port="20890"/> <bean id="demoService" class="org.apache.dubbo.samples.basic.impl.DemoServiceImpl"/> <dubbo:service interface="org.apache.dubbo.samples.basic.api.DemoService" ref="demoService"/> </beans>
上述代码中我们有看到dubbo
自定义了一套自己的标签,dubbo:application ,dubbo:registry ,dubbo:protocol,dubbo:service我们心中是不是有点小疑问:这些标签在Spring
项目启动的时候是如何被Spring
管理的?是怎样被Spring
来识别的?如果我们自己随便定义一个标签Spring
是否能够识别?我们去翻翻Spring
的官网发现这玩意其实就是Spring
提供的 XML schema
的扩展支持。只要按照它的步骤来,我们就可以配置任何我们自定义的标签。XML schema
扩展机制是什么?这个也许好多人没听过:
★Spring 为基于 XML 构建的应用提供了一种扩展机制,用于定义和配置 Bean。它允许使用者编写自定义的 XML bean 解析器,并将解析器本身以及最终定义的 Bean 集成到 Spring IOC 容器中。
”
我们可以看看官网https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#xml-custom 10.2. XML Schema Authoring 这个是主要介绍它的。
官网有介绍,要实现一个自定义的XML Schema
总共需要4步:
★编写一个 XML schema 文件描述的你节点元素。
编写一个 NamespaceHandler 的实现类
编写一个或者多个 BeanDefinitionParser 的实现 (关键步骤).
注册上述的 schema 和 handler。
”
既然只要按照这四步来,那我们就照着这个文档来自己实现一个。
编写一个javajr.xsd 放入项目的resources/META-INF文件夹里面(这个也可以是其他路径)
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:tool="http://www.springframework.org/schema/tool" xmlns="https://www.javajr.cn/schema/javajr" targetNamespace="https://www.javajr.cn/schema/javajr"> <xsd:import namespace="http://www.springframework.org/schema/beans"/> <xsd:element name="application"> <xsd:complexType> <xsd:complexContent> <xsd:extension base="beans:identifiedType"> <xsd:attribute name="website" type="xsd:string" use="required"/> <xsd:attribute name="weixin" type="xsd:string" use="required"/> </xsd:extension> </xsd:complexContent> </xsd:complexType> </xsd:element> </xsd:schema>
targetNamespace="https://www.javajr.cn/schema/javajr"
这里targetNamespace
的地址后面有用到。
这里我们就定义了一个元素application 里面有两个属性分别为website
和weixin
。
package org.spring.demo.schema; import org.springframework.beans.factory.xml.NamespaceHandlerSupport; public class MyNamespaceHandler extends NamespaceHandlerSupport { @Override public void init() { // 这个名字也不是随便取的,上面编写xsd的根节点元素的name, <xsd:element name="application"> registerBeanDefinitionParser("application", new MyBeanDefinitionParser()); } }
这个NamespaceHandler
就是将一个 XML
节点解析成 IOC
容器中的一个实体类。也就是说相当于在xml
里面的配置的对象,通过Spring ioc
容器管理起来了
package org.spring.demo.schema; import org.spring.demo.domain.JavajrDomain; 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 MyBeanDefinitionParser extends AbstractSingleBeanDefinitionParser { @Override protected Class<?> getBeanClass(Element element) { return JavajrDomain.class; } @Override protected void doParse(Element element, BeanDefinitionBuilder bean) { // this however is an optional property String website = element.getAttribute("website"); if (StringUtils.hasText(website)) { bean.addPropertyValue("website",website); } String weiXin = element.getAttribute("weixin"); if (StringUtils.hasText(weiXin)) { bean.addPropertyValue("weixin",weiXin); } } }
上面在这个实现类只是简单的做了一个赋值操作,你如果需要有自己的逻辑业务也可以自行来实现。上面还有一个JavajrDomain这个实体类就不贴代码,就一个简单的javabean
里面包含了两个属性weixin和website。
最后在resources/META-INF
目录下添加两个配置文件(spring.handler和spring.schema
):
resources/META-INF/spring.handlers
https\://www.javajr.cn/schema/javajr=org.spring.demo.schema.MyNamespaceHandler
resources/META-IN/spring.schemas
https\://www.javajr.cn/schema/javajr.xsd=META-INF/javajr.xsd
在这个地方的时候我们其实可以以版本号来进行命名,方便我们可以使用多个不同的版本,Spring-beans 就是这么玩的。
在resources
目录下新建一个applicationContext.xml
文件
这个文件就是使用下我们我们自己自定义的schema
,这个文件需要注意的就是上面标红的这几行,一般如果我们有引入过第三方的框架,比如mq
、或者dubbo
等它们都有自定义的这些玩意。
public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); JavajrDomain bean = ctx.getBean(JavajrDomain.class); System.out.println(bean.toString()); }
我们可以看到控制台输出
JavajrDomain{weixin='javajr8', website='javajr.cn'}
到这里我们自己实现的一个 XML schema
就完成了,是不是很简单,只要照着官方文档撸就可以了。照着撸的过程可能有几个小细节需要注意下引入 XML schema
的时候需要注意下空格,或者一些特殊符号。上述代码已经提交到了gitee上https://gitee.com/javajr/spring-schema-demo
感兴趣的朋友可以直接下载下来run
下,不过还是不建议这么玩,最好还是自己动手去尝试下,毕竟也就四步,照着文档来。
在文章开始的时候我们有介绍dubbo
自定义的XML schema
,下面我们一起打开dubbo
源码看看它是如何来实现的,看下面这个截图,也是按照那四步来的。
现在有了SpringBoot
之后以前用这个 XML schema
配置的框架,大多数都会有对应的starter
来进行封装,starter
的使用比起 XML schema
的使用还是简单多了,开箱即用,无需编写很多的配置文件。
以上是“Spring自定义XML schema 扩展的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。