Dubbo基于Spring可扩展 Schema提供自定义配置支持分析


声明:本文转载自https://my.oschina.net/u/3729778/blog/1575550,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

      Dubbo提供了很好的配置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:rpc="http://code.jiupai.com/schema/rpc"        xmlns:context="http://www.springframework.org/schema/context"        xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd                   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd                         http://code.jiupai.com/schema/rpc http://code.jiupai.com/schema/rpc/rpc.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">          <dubbo:application name="dubbo-client"/>         <dubbo:registry address="zookeeper://127.0.0.1:2181"/>                <!--dubbo service-->         <bean id="demoService" class="com.alibaba.dubbo.demo.provider.DemoServiceImpl" />          <dubbo:service protocol="dubbo" interface="com.alibaba.dubbo.demo.DemoService" ref="demoService"/>         <dubbo:service id="helloService" interface="com.alibaba.dubbo.demo.provider.DemoService"/> </beans>

这种方式用起来非常方便简洁,现在大多数开源框架都会提供这种基于xml配置的方式。这些都是基于 Spring 可扩展 Schema 提供自定义配置支持。

        虽然基于Spring的标准的Bean配置可以满足我们对于系统的简单配置,但是如果遇到需要配置较为复杂的或者需要更多的丰富控制的时候,基于标准的Spring的Bean的配置就显得有点捉襟见肘了。此时有些方法可以使用:

(1)自己使用相关的xml工具类去解析xml定义,然后转化成目标的配置对象,这种方式可以实现深度的定制化,但是实现起来比较繁琐,特别是在配置项非常复杂的时候,解析起来也是一场的繁琐。

(2)使用Spring提供的可扩展Schema的支持,可以让我们不用重复的去造轮子,从一定程度上减少工作量,并且可以达到不错的效果。

基于Spring的扩展Schema的方式完成一个自定义配置一般需要以下步骤:

a、设计配置属性和JavaBean 
b、编写XSD文件 
c、编写NamespaceHandler和BeanDefinitionParser完成解析工作 
d、编写spring.handlers和spring.schemas串联起所有部件 
e、在Bean文件中应用 
下面分析Dubbo是如何基于Spring的可扩展Schema的方式实现简单配置即可实现服务注入的。

1、首先我们拿到Dubbo的配置,查看其在配置文件中的使用:

点开标签: 

<dubbo:registry address="zookeeper://127.0.0.1:2181"/>

可以看到标签定义文件(xsd一般存放在classpath下,一般都放在META-INF目录下):com/alibaba/dubbo/2.4.9/dubbo-2.4.9.jar!/META-INF/dubbo.xsd中的定义如下:

<xsd:element name="registry" type="registryType">    <xsd:annotation>        <xsd:documentation><![CDATA[ The registry config ]]></xsd:documentation>     </xsd:annotation> </xsd:element>

2、xsd还没法让应用感知到,spring提供了spring.handlers和spring.schemas这两个配置文件来完成这项工作,这两个文件需要我们自己编写并放入META-INF文件夹中,这两个文件的地址必须是META-INF/spring.handlers和META-INF/spring.schemas,spring会默认去载入它们,本例中spring.handlers如下所示:

通过com/alibaba/dubbo/2.4.9/dubbo-2.4.9.jar!/META-INF/spring.schemas和com/alibaba/dubbo/2.4.9/dubbo-2.4.9.jar!/META-INF/spring.handlers文件将功能串起来

定义如下:

http\://code.alibabatech.com/schema/dubbo/dubbo.xsd=META-INF/dubbo.xsd
http\://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler

两个定义可以将前面说的dubbo.xsd与对应的解析类com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler关联起来。

3、com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler解析配置。

NamespaceHandler会根据schema和节点名找到某个BeanDefinitionParser,然后由BeanDefinitionParser完成具体的解析工作。因此需要分别完成NamespaceHandler和BeanDefinitionParser的实现类,Spring提供了默认实现类NamespaceHandlerSupport和AbstractSingleBeanDefinitionParser,简单的方式就是去继承这两个类。Dubbo就是采取这种方式,代码如下:

// package com.alibaba.dubbo.config.spring.schema;  import com.alibaba.dubbo.common.Version; import com.alibaba.dubbo.config.ApplicationConfig; import com.alibaba.dubbo.config.ConsumerConfig; import com.alibaba.dubbo.config.ModuleConfig; import com.alibaba.dubbo.config.MonitorConfig; import com.alibaba.dubbo.config.ProtocolConfig; import com.alibaba.dubbo.config.ProviderConfig; import com.alibaba.dubbo.config.RegistryConfig; 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;  public class DubboNamespaceHandler extends NamespaceHandlerSupport {     public DubboNamespaceHandler() {     }      public void init() {         this.registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));         this.registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));         this.registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));         this.registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));         this.registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));         this.registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));         this.registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));         this.registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));         this.registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));         this.registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true));     }      static {         Version.checkDuplicate(DubboNamespaceHandler.class);     } }

可以看到这个里面定义了很多的解析器,而且解析是按照顺序进行的,具体可以点进去跟踪代码阅读。

参考:基于Spring可扩展Schema提供自定义配置支持(spring配置文件中 配置标签支持),里面介绍的已经很全了 关于Spring的Schema的资料

http://www.cnblogs.com/jifeng/archive/2011/09/14/2176599.html

本文发表于2017年11月18日 18:33
(c)注:本文转载自https://my.oschina.net/u/3729778/blog/1575550,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2331 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1