Spring 扩展点实践:整合 Apache Dubbo

在上一篇文章 Spring 扩展点概览及实践
中介绍了 Spring 内部存在的扩展点。 Spring 扩展点实践:整合 MyBATIS
中,D瓜哥带大家了解了一下 MyBATIS 如何利用 Spring 的扩展点实现了与 Spring 的完美整合。现在,学以致用,我们继续来分析一下 Spring 与 Apache Dubbo 的整合流程。

示例程序

Apache Dubbo 仓库中就有很完整的示例。D瓜哥直接拿来使用就不再搭建示例程序了。

首先,需要启动一个 ZooKeeper 实例。查看 Dubbo 的依赖可以看出,最新版代码依赖的 ZooKeeper 是 3.4.13 版。所以,为了最好的兼容性,就要选用 3.4.X 版的 ZooKeeper 服务器。D瓜哥直接使用 Docker 启动 ZooKeeper 了。命令如下:

docker run --rm --name zookeeper -d -p 2181:2181 zookeeper:3.4.14

这次我们使用 Apache Dubbo
dubbo-demo/dubbo-demo-xml
示例。

第二步,启动服务提供者程序,找到 DUBBO/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-provider/src/main/java/org/apache/dubbo/demo/provider/Application.java
,运行该类。

第三步,运行服务消费者程序,找到 DUBBO/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-consumer/src/main/java/org/apache/dubbo/demo/consumer/Application.java
,运行该类。

如果没有任何错误,则在终端可以看到 result: async result
输出。

在开始正餐之前,D瓜哥先给大家来个开胃菜。

Spring 插件机制简介

不知道大家有没有想过一个问题:Spring 框架是如何支持越来越多的功能的?

在D瓜哥了解到 Spring 的插件机制后,非常叹服 Spring 精巧的设计和灵活的扩展性。闲言少叙,好戏上演。

这里再问大家一个问题:

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           https://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/aop
                           https://www.springframework.org/schema/aop/spring-aop.xsd
                           http://www.springframework.org/schema/context
                           https://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/tx
                           https://www.springframework.org/schema/tx/spring-tx.xsd
                           http://dubbo.apache.org/schema/dubbo
                           http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

	<context:annotation-config/>

	<tx:annotation-driven proxy-target-class="true" order="0"/>

	<aop:config>
		<aop:advisor pointcut="execution(* ..ITestBean.(..))" advice-ref="txAdvice"/>
	</aop:config>

	<tx:advice id="txAdvice">
		<tx:attributes>
			<tx:method name="get*" timeout="5" read-only="true"/>
			<tx:method name="set*"/>
			<tx:method name="exceptional"/>
		</tx:attributes>
	</tx:advice>


	<bean id="transactionManager" class="org.springframework.transaction.testfixture.CallCountingTransactionManager"/>

	<bean id="testBean" class="org.springframework.beans.testfixture.beans.TestBean"/>

</beans>

这是非常典型的 Spring XML 配置。相信大家都见过。大家有没有想过,Spring 是怎么处理这些不同的命名空间的?如果说 AOP、事务这些是 Spring 内置支持的功能,这样配置,Spring 可以正确解析。但是,Dubbo 的配置又是怎么回事?

回答这个问题,就要说起 Spring 的插件机制。在 Spring 的插件机制面前,无论是 Dubbo,还是 Spring 的 AOP、事务管理都是人人平等的。它们都是依靠 Spring 的插件机制插拔在 Spring 核心模块之上的。

这篇文章不是专门介绍 Spring 插件机制的。这里抛砖引玉,对 Spring 插件机制做个简介。后续有机会再做更详细的介绍和说明。

要利用 Spring 插件机制,需要做这么几个事情:

  1. 定义自己业务的类。

  2. 编写 XSD 文件,定义自己的 XML 格式,将文件放在 src/main/resources/META-INF
    目录下。

  3. 针对每一个标签,定义一个实现 BeanDefinitionParser
    接口的类,在 parse
    方法中完成对这个标签的解析工作,将其转化成一个 BeanDefinition
    对象。

  4. 继承 NamespaceHandlerSupport
    类,在 init()
    方法中,使用 registerBeanDefinitionParser()
    将标签名称和上面写的 BeanDefinitionParser
    实现类之间建起起对应关系。

  5. 创建 src/main/resources/META-INF/spring.schemas
    文件,在其中写上: http/://www.diguage.com/schema/diguage/diguage.xsd=META-INF/diguage.xsd
    ,为该 XSD 文件定义唯一的命名空间。

  6. 创建 src/main/resources/META-INF/spring.handlers
    文件,在其中写上: http/://www.diguage.com/schema/diguage=com.diguage.schema.DiguageNamespaceHandler

完成上面这些步骤就相当于制作了一个 Spring 插件。这样就可以在 Spring XML 配置文件中,像使用 AOP、事务管理那样来使用这个新插件了。

仔细想想,Spring 的插件机制还是挺简单的:首先,定义一个 Bean 类,然后设计 XSD 文件来对 Bean 的属性进行定义。用户在使用插件时,使用 XML 来定义 Bean 类的属性值,再自定义的 BeanDefinitionParser
实现类将 XML 中的配置信息解析出来,封装在 BeanDefinition
(关于 BeanDefinition
的更多信息,请移步 深入剖析 Spring 核心数据结构:BeanDefinition
)。到了 BeanDefinition
之后,Spring 在内部就可以统一处理了。

下面,结合代理来具体说明一下 Apache Dubbo 的实现过程。

Apache Dubbo 插件机制解析

Apache Dubbo 最初就说通过 Spring 插件机制实现了它与 Spring 的整合过程。

  1. 相关业务类有 ApplicationConfig
    ModuleConfig
    RegistryConfig
    ConfigCenterBean
    MetadataReportConfig
    MonitorConfig
    MetricsConfig
    SslConfig
    ProviderConfig
    ConsumerConfig
    ProtocolConfig
    ServiceBean
    ReferenceBean
    。这些类的命名也都非常讲究,见文知意,与 Dubbo 常见配置可以说是一一对应。

  2. Dubbo 的 XSD 定义在 dubbo.xsd
    ,懂 XSD 的朋友应该都能看出来,这个文件就是规范上一步提到的类的属性的。

  3. DubboBeanDefinitionParser
    实现了 BeanDefinitionParser
    接口,用于解析 XML 配置,并将其“翻译”为第一步中那些类的对象。另外,还注册了一个 AnnotationBeanDefinitionParser
    ,用来处理 annotation
    标签,进而用来处理注解。

  4. DubboNamespaceHandler
    继承了 NamespaceHandlerSupport
    ,并且在 init()
    方法中完成了对上述类的 DubboBeanDefinitionParser
    注册。

  5. dubbo-config/dubbo-config-spring/src/main/resources/META-INF
    目录下,有 spring.schemas
    文件和 spring.handlers
    文件。

下面以调试跟进的方式来分析整个处理过程。

Apache Dubbo 配置解析

这里使用示例程序中的配置文件:

dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-provider/src/main/resources/spring/dubbo-provider.xml
<?xml version="1.0" encoding="UTF-8"?>
<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 metadata-type="remote" name="demo-provider"/>

    <dubbo:metadata-report address="zookeeper://127.0.0.1:2181"/>

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

    <dubbo:protocol name="dubbo"/>

    <bean id="demoService" class="org.apache.dubbo.demo.provider.DemoServiceImpl"/>

    <dubbo:service interface="org.apache.dubbo.demo.DemoService" ref="demoService"/>
</beans>

org.apache.dubbo.config.spring.schema.DubboNamespaceHandler#init
方法、 org.apache.dubbo.config.spring.schema.DubboNamespaceHandler#parse
方法 和 org.apache.dubbo.config.spring.schema.DubboBeanDefinitionParser#parse(Element, ParserContext)
方法打断点开始调试。注意:这三个方法都是重载方法,很容易识别。

先写这些,明天继续…

原文 

https://www.diguage.com/post/spring-extensions-and-dubbo/

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » Spring 扩展点实践:整合 Apache Dubbo

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址