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

相关推荐
贾斯汀玛尔斯1 小时前
每天学一个算法--LSM-Tree(Log-Structured Merge Tree)
java·算法·lsm-tree
bitt TRES1 小时前
springboot与springcloud对应版本
java·spring boot·spring cloud
Y001112362 小时前
JavaWeb-end
java·servlet·web
bzmK1DTbd2 小时前
Git版本控制:Java项目中的分支管理与合并策略
java·开发语言·git
JWASX4 小时前
【RocketMQ 生产者和消费者】- 事务源码分析(1)
java·rocketmq·java-rocketmq
AlunYegeer5 小时前
JAVA,以后端的视角理解前端。在全栈的路上迈出第一步。
java·开发语言·前端
DFT计算杂谈6 小时前
自动化脚本一键绘制三元化合物相图
java·运维·服务器·开发语言·前端·python·自动化
2301_771717216 小时前
Spring Boot 自动配置核心注解
java·spring boot·mybatis
小Y._6 小时前
面试被问synchronized锁升级,这5个问题答不上来直接挂!
java
姚青&7 小时前
测试技术体系
java·python