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扫描注入点 → 检查本地服务 → 创建/获取代理 → 完成依赖注入

相关推荐
ps酷教程4 小时前
Jackson 解决没有无参构造函数的反序列化问题
java
NiceCloud喜云4 小时前
Opus 4.8 的 Effort Control 怎么选:Low 到 Max 五档策略
android·java·大数据·前端·c++·python·spring
_日拱一卒5 小时前
LeetCode:994腐烂的橘子
java·数据结构·算法·leetcode·深度优先
隔窗听雨眠6 小时前
Nginx网关响应慢排查手记
java·服务器·nginx
智慧物业老杨6 小时前
智慧物业合同周期管理系统:从风险预警到智能交接的全流程数智化落地方案
java·人工智能·python
源码宝6 小时前
MES系统源码:Java8 + SpringBoot2.7 + MySQL8 + Redis,后端源码清爽易扩展
java·后端·源码·springboot·mes系统·源码二开·mes源码
JAVA社区7 小时前
Java高级全套教程(十)—— SpringCloudAlibaba超详细实战详解
java·开发语言·spring cloud·面试·职场和发展
金銀銅鐵7 小时前
[Java] 如何理解 class 文件中方法的 descriptor?
java·后端
云烟成雨TD7 小时前
Spring AI Alibaba 1.x 系列【63】AI Agent 长期记忆
java·人工智能·spring
憧憬成为java架构高手的小白7 小时前
苍穹外卖--day09
java·spring boot·百度