Spring与Dubbo整合原理与源码分析

一、整体架构与启动流程

Spring 与 Dubbo 整合的​核心入口是 @EnableDubbo ​,整体流程一句话概括:​Spring 启动 → 加载 Dubbo 配置 → 扫描 @Service 并导出服务 → 处理 @Reference 并注入代理 → 完成 RPC 调用准备​。

标准启动代码

java 复制代码
@Configuration
@EnableDubbo(scanBasePackages = "org.apache.dubbo.demo.provider")
@PropertySource("classpath:/spring/dubbo-provider.properties")
static class ProviderConfiguration {
}

public class Application {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext context =
            new AnnotationConfigApplicationContext(ProviderConfiguration.class);
        context.start();
        System.in.read();
    }
}
  • @PropertySource:加载 .properties 配置到 Spring 环境
  • @EnableDubbo:开启 Dubbo 全能力,扫描指定包下的 @Service / @Reference

二、核心注解:@EnableDubbo 拆解

@EnableDubbo 本质是​组合注解​,内部包含两个关键注解:

  1. @EnableDubboConfig:负责配置文件解析与绑定
  2. @DubboComponentScan*:负责注解扫描与服务处理
java 复制代码
// 简化伪代码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@EnableDubboConfig
@DubboComponentScan
public @interface EnableDubbo {
    String[] scanBasePackages() default {};
}

三、模块 1:Dubbo 配置文件解析原理

核心链路

@EnableDubboConfigDubboConfigConfigurationRegistrarDubboConfigBindingsRegistrarDubboConfigBindingRegistrarDubboConfigBindingBeanPostProcessorDefaultDubboConfigBinder

1. DubboConfigConfigurationRegistrar

  • 被 @EnableDubboConfig 的 @Import 导入
  • 注册两个配置类:
    • Single:单例配置(dubbo.application、dubbo.registry...)
    • Multiple:多实例配置(dubbo.applications、dubbo.protocols...)

2. DubboConfigBindingRegistrar

  • 解析 properties 前缀(如 dubbo.application
  • 按前缀生成对应 Config BeanDefinition
    • dubbo.applicationApplicationConfig
    • dubbo.registryRegistryConfig
    • dubbo.protocols.p1ProtocolConfig(beanName=p1)

3. DubboConfigBindingBeanPostProcessor

  • 只处理 Dubbo 生成的 AbstractConfig 子类 Bean
  • 调用 DefaultDubboConfigBinder 完成属性赋值

4. DefaultDubboConfigBinder

  • 基于 Spring DataBinder 技术

  • 把 properties 键值对绑定到 Config 对象属性

  • 示例: → ApplicationConfig.name = dubbo-demo-provider

    复制代码
    dubbo.application.name=dubbo-demo-provider

配置解析总结

Spring 环境加载 → 按前缀解析 → 生成 Config Bean → 后置处理器绑定属性值​。


四、模块 2:@Service 注解解析与服务导出

核心链路

@DubboComponentScanDubboComponentScanRegistrarServiceAnnotationBeanPostProcessorDubboClassPathBeanDefinitionScanner → 生成服务实现 Bean + ServiceBean → 触发 export() 服务导出

1. DubboComponentScanRegistrar

  • 注册两个核心后置处理器:
    1. ServiceAnnotationBeanPostProcessor:处理 @Service
    2. ReferenceAnnotationBeanPostProcessor:处理 @Reference

2. ServiceAnnotationBeanPostProcessor

  • 实现 BeanDefinitionRegistryPostProcessor
  • 构造 DubboClassPathBeanDefinitionScanner 扫描器

3. DubboClassPathBeanDefinitionScanner

  • 继承 Spring ClassPathBeanDefinitionScanner
  • useDefaultFilters = false:不扫描 Spring @Component,只扫 Dubbo @Service

4. 扫描后生成两个 Bean

  1. 服务实现类本身:普通 Spring Bean
  2. ServiceBean :Dubbo 服务载体,包含:
    • ref:服务实现对象
    • interface:服务接口
    • registries:注册中心
    • protocols:协议

5. 服务导出触发

  • ServiceBean 实现 ApplicationListener
  • Spring 启动完成 → onApplicationEvent()export() → 服务暴露完成

五、模块 3:@Reference 注解解析与服务引入

核心链路

ReferenceAnnotationBeanPostProcessor → 查找 @Reference 注入点 → 生成/获取代理对象 → 完成属性注入

1. ReferenceAnnotationBeanPostProcessor

  • 父类:AnnotationInjectedBeanPostProcessor
  • 属于 InstantiationAwareBeanPostProcessorAdapter
  • 拦截 Spring 依赖注入,处理 @Reference 字段/方法

2. 注入流程

  1. 找到被 @Reference 标记的​注入点​(字段/setter)

  2. 计算 referencedBeanName(接口 +group+version)

  3. 检查本地是否存在对应 ServiceBean

    • 存在:直接取本地 ref 对象
    • 不存在:创建远程代理

    需要我把这份​思维导图转成图片格式 ​,或帮你生成可直接发布的公众号/博客排版文章​吗?

  4. 生成/获取 ReferenceBean(FactoryBean)

  5. 调用 ReferenceBean.get() 得到 Dubbo 代理对象

  6. 反射注入到字段/方法

3. 关键缓存机制

  • referenceBeanCache:缓存已创建的 ReferenceBean
  • localReferenceBeanInvocationHandlerCache:缓存本地服务代理,避免重复创建

六、三大核心模块完整总结

  1. 配置解析 @EnableDubboConfig → 加载 properties → 生成 Config Bean → DataBinder 绑定属性
  2. 服务导出(@Service扫描 @Service → 生成服务实现 Bean + ServiceBean → Spring 启动完成 → export() 暴露服务
  3. 服务引入(@Reference扫描注入点 → 检查本地服务 → 创建/获取代理 → 完成依赖注入

相关推荐
Gopher_HBo2 小时前
BlockingQueue详解
java·后端
白露与泡影2 小时前
为什么在IDEA使用@Autowired会报黄?
java·ide·intellij-idea
我登哥MVP2 小时前
【Spring6笔记】 - 15 - Spring中的八大设计模式
java·spring boot·笔记·spring·设计模式·intellij-idea
蚰蜒螟2 小时前
深入剖析 Tomcat 9.0.53 源码:Web 资源管理与类加载机制
java·前端·tomcat
m0_475064502 小时前
Spring AI文档切片
java·人工智能·spring
我登哥MVP2 小时前
【SpringMVC笔记】 - 1 - SpringMVC入门
java·spring boot·spring·tomcat·maven·intellij-idea·springmvc
Arva .2 小时前
Spring 事务传播机制 速记
java·数据库·spring
0xDevNull2 小时前
Spring Boot 2.0动态多数据源切换实战教程
java·后端
语戚2 小时前
力扣 2463. 最小移动总距离 —— 动态规划 & 贪心排序全解(Java 实现)
java·算法·leetcode·贪心算法·动态规划·力扣·dp