`
manzhizhen
  • 浏览: 293736 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Dubbo源代码实现一:切入Spring

阅读更多

        Dubbo是阿里开源的一个高性能服务框架,提供了服务注册、RPC服务调用、调用均衡、服务监控和服务failover等功能。如果你还未使用过Dubbo框架,请先参考dubbo提供的官方文档,比如:http://www.oschina.net/p/dubbo?fromerr=iVZFqWON。

        Dubbo框架中有两个重要角色:(服务)提供者和(服务)消费者,这里为了简单起见,将包含了dubbo提供者或消费者功能的应用模块通称为dubbo客户端

        带着问题看源代码,才能有收获。

        进入正题,现在大多数java应用都离不开Spring,所以其他java解决方案,或多或少都会支持在Spring中使用,dubbo也不例外。在我记忆中,凡是想在Spring容器中发挥作用的框架,无非都是提供对应的Spring Bean来注入到Spring容器中,dubbo也一样。在源代码的dubbo-container-spring模块中,唯一的类SpringContainer说明了这一点,它的start()方法直接通过ClassPathXmlApplicationContext来启动Spring容器。有人立马会问,SpringContainer的start()方法由谁调用?答案就是com.alibaba.dubbo.container.Main,它是dubbo的入口,Main类中的main方法将依次调用dubbo内置的Container的start()方法。如果没有配置Spring xml文件的路径,dubbo将会默认采用classpath*:META-INF/spring/*.xml。

         那么问题来了,Spring是如何识别dubbo的那些自定义标签的?Spring为了支持用户自定义类加载到Spring容器,提供了org.springframework.beans.factory.xml.NamespaceHandler接口和org.springframework.beans.factory.xml.NamespaceHandlerSupport抽象类,NamespaceHandler#init方法会在对象的构造函数调用之后、属性初始化之前被DefaultNamespaceHandlerResolver调用。dubbo的DubboNamespaceHandler类正是继承了NamespaceHandlerSupport,其代码实现如下:

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));
    }

}

        registerBeanDefinitionParser方法有父抽象了类NamespaceHandlerSupport的默认实现,第一个参数是elementName,即元素名称,即告诉Spring你要解析哪个标签,第二个参数是BeanDefinitionParser的实现类,BeanDefinitionParser是Spring用来将xml元素转换成BeanDefinition对象的接口。dubbo的DubboBeanDefinitionParser类就实现了这个接口,负责将标签转换成bean定义对象BeanDefinition。dubbo给其返回的BeanDefinition设置了下列属性:

        beanDefinition.setBeanClass(beanClass);
        beanDefinition.setLazyInit(false);

        beanDefinition.getPropertyValues().addPropertyValue("id", id);

        如果是dubbo:protocol标签,dubboh还会检查所有已经包含protocol属性的BeanDefinition且protocol属性对应的值是ProtocolConfig对象的bean,将其属性的protocol值设置成当前的bean引用:

        definition.getPropertyValues().addPropertyValue("protocol", new RuntimeBeanReference(id));

        如果是dubbo服务提供者的dubbo:service标签,则还会设置ref属性为对应接口class的实现类bean:

        beanDefinition.getPropertyValues().addPropertyValue("ref", new BeanDefinitionHolder(classDefinition, id + "Impl"));

        有没有人想过,当使用dubbo服务提供者的dubbo:service标签时,如果我既不设置id,也不设置name,则dubbo给它的ServiceBean在Spring容器中定义的ID是什么? 答案就是:

            if (generatedBeanName == null || generatedBeanName.length() == 0) {
                generatedBeanName = beanClass.getName();
            }
            id = generatedBeanName;
            int counter = 2;
            while(parserContext.getRegistry().containsBeanDefinition(id)) {
                id = generatedBeanName + (counter ++);
            }

        有人就会问,Spring怎么知道你自定义了NamespaceHandlerSupport的实现类?Spring容器会默认加载classpath/META-INF下的spring.handlers和spring.schemas文件,来加载名空间处理器和xsd,所以dubbo-config-spring包下的META-INF目录下就有这两个文件。

        最后,DubboNamespaceHandler类中的静态代码块去classpath下检查是否有其他的同名class,否则会打错误日志,这个是为什么呢?防止不同的类加载器重复加载DubboNamespaceHandler?不得而知。

 

     

 

分享到:
评论

相关推荐

    Spring+mybatis+dubbo整合源代码及jar包

    通过Spring_Mybatis_Dubbo_Jars.zip和Spring_Mybatis_Dubbo2.zip这两个压缩包,你可以获取到整合所需的所有依赖包和源代码,从而快速搭建起这个框架。这将帮助开发者更快地理解并掌握这三大框架的协同工作方式,提高...

    Dubbo源代码(2.8.4)

    总的来说,Dubbo 2.8.4的源代码是一个深度学习分布式服务治理框架的好材料,它揭示了服务治理的核心机制和实现细节,对于理解微服务架构和提升Java开发能力大有裨益。通过深入研究,开发者可以更好地利用Dubbo来构建...

    spring_dubbo spring_dubbo spring_dubbo

    spring_dubbo spring_dubbospring_dubbospring_dubbospring_dubbospring_dubbospring_dubbospring_dubbospring_dubbospring_dubbospring_dubbospring_dubbospring_dubbospring_dubbospring_dubbospring_dubbospring_...

    Dubbo源代码(2.5.4)

    【Dubbo源代码(2.5.4)】是一份重要的开源项目资源,它包含了Dubbo框架在2.5.4版本的完整源代码。Dubbo是中国阿里巴巴公司贡献的高性能、轻量级的服务治理框架,它专注于服务调用、监控和服务治理。这个版本的源...

    Apache Dubbo:Dubbo高级特性:服务降级与熔断实战

    Apache Dubbo:Dubbo高级特性:服务降级与熔断实战 Dubbo是著名的RCP框架,文档内有干货,提供代码和可复现的命令,值得借鉴。

    dubbo从入门到精通教程

    dubbo的实现细节包括: * Dubbo框架的核心模块 * Dubbo的RPC机制 * Dubbo的服务注册和发现机制 * Dubbo的服务调用和监控机制 dubbo的Zookeeper集成包括: * Zookeeper的作用 * Dubbo和Zookeeper的集成方式 * ...

    Apache Dubbo:Dubbo服务治理:服务路由与动态配置

    ### Apache Dubbo:服务治理——服务路由与动态配置 #### 一、服务治理的重要性 在当前流行的微服务架构中,由于各个服务之间存在着频繁而复杂的交互,如何有效地管理和控制这些服务成为了确保整个系统稳定性和可...

    Apache Dubbo:Dubbo服务治理:服务熔断与超时重试

    ### Apache Dubbo:服务熔断与超时重试 #### 一、服务熔断基础 ##### 1.1 服务熔断的概念 服务熔断,作为一种重要的服务稳定性保障措施,在分布式系统中扮演着至关重要的角色。它的工作原理是,当某个服务节点...

    spring-dubbo-spring-boot.rar_java编程_spring_spring boot_threwwab_

    本教程将深入探讨如何在Spring Boot项目中集成Spring Dubbo,实现高效的服务调用和管理。 一、Spring框架与Spring Boot Spring框架以其强大的依赖注入(DI)和面向切面编程(AOP)能力,为Java开发者提供了灵活且...

    dubbo server+client 完整代码

    【Dubbo Server+Client 完整代码】是一个深入学习和实践Dubbo框架的实例项目,它涵盖了服务端(Server)和服务消费者端(Client)的完整实现。Dubbo是阿里巴巴开源的一款高性能、轻量级的Java远程服务框架,它强调了...

    Apache Dubbo:Dubbo高级特性:服务版本与分组

    - **配置文件方式**:在服务提供者和消费者的配置文件中,使用 `<dubbo:service>` 或 `<dubbo:reference>` 标签的 `version` 属性来指定服务版本。 - **服务提供者配置**: ```xml <dubbo:service interface=...

    Apache Dubbo:Dubbo核心概念:服务提供者与消费者

    ### Apache Dubbo:服务提供者与消费者核心概念详解 #### 一、Apache Dubbo概览 **Apache Dubbo**是一款高性能、轻量级的开源微服务框架,最初由阿里巴巴内部开发并在2008年开始使用,随后在2011年开源。自2017年...

    dubbo2.8.4.jar

    如果使用dubbo遇到错误:com.alibaba.dubbo.remoting.RemotingException: Fail to decode request due to: RpcInvocation 请下载这个jar,替换掉你项目中的那个jar,应该可以解决。

    Spring Boot 整合 Dubbo + Zookeeper 实现服务者与消费者的数据调用

    1.SpringBoot聚合工程整合Dubbo,实现服务提供者与服务消费者的数据调用, 2.该项目提高了自己对Spring Boot整合Dubbo的理解,并深刻的认识到了服务者与消费者之间的调用及流程 4. Dubbo配置全部采用yml文件配置,...

    dubbo源代码

    dubbo分布式服务框架,方便大家对分布式服务的学习,方便对dubbo的扩展

    dubbo示例代码dubbo-sample

    【Dubbo 示例代码详解】 Dubbo 是阿里巴巴开源的一款高性能、轻量级的Java服务治理框架,它主要提供了RPC(远程过程调用)服务,并且包含了服务注册与发现、负载均衡、容错处理、监控等全面的服务治理功能。本示例...

    dubbo2.8.4源代码

    【标题】"Dubbo 2.8.4 源代码" 涵盖了分布式服务框架的核心技术,是阿里巴巴开源的一款高性能、轻量级的服务治理框架。它为开发者提供了微服务开发所需的诸多功能,包括服务注册与发现、负载均衡、调用链路监控等。...

    Apache Dubbo:Dubbo监控与运维:服务性能分析

    ### Apache Dubbo:Dubbo监控与运维:服务性能分析 #### 一、Dubbo监控概述 ##### 1.1 Dubbo监控的重要性 在现代微服务架构中,由于服务之间存在着复杂的调用关系,任何单一服务的性能问题都有可能对整体系统稳定...

    dubbo实现demo

    - 在服务提供者端,通过`dubbo:service`标签配置服务接口、实现类、版本等信息,暴露服务。 - 在服务消费者端,通过`dubbo:reference`标签配置服务接口、版本等信息,引用远程服务。 4. **配置文件详解**: - `...

    dubbo xsd的支持

    4. `<dubbo:service>`:用于暴露服务,定义接口、版本、实现类、调用方式、超时时间等参数。 5. `<dubbo:reference>`:用于引用远程服务,指定服务接口、版本、调用方式、超时时间等,方便客户端消费服务。 6. `...

Global site tag (gtag.js) - Google Analytics