
一、整体架构与启动流程
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 本质是组合注解,内部包含两个关键注解:
- @EnableDubboConfig:负责配置文件解析与绑定
- @DubboComponentScan*:负责注解扫描与服务处理
java
// 简化伪代码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@EnableDubboConfig
@DubboComponentScan
public @interface EnableDubbo {
String[] scanBasePackages() default {};
}
三、模块 1:Dubbo 配置文件解析原理
核心链路
@EnableDubboConfig → DubboConfigConfigurationRegistrar → DubboConfigBindingsRegistrar → DubboConfigBindingRegistrar → DubboConfigBindingBeanPostProcessor → DefaultDubboConfigBinder
1. DubboConfigConfigurationRegistrar
- 被 @EnableDubboConfig 的 @Import 导入
- 注册两个配置类:
- Single:单例配置(dubbo.application、dubbo.registry...)
- Multiple:多实例配置(dubbo.applications、dubbo.protocols...)
2. DubboConfigBindingRegistrar
- 解析 properties 前缀(如
dubbo.application) - 按前缀生成对应 Config BeanDefinition
dubbo.application→ApplicationConfigdubbo.registry→RegistryConfigdubbo.protocols.p1→ProtocolConfig(beanName=p1)
3. DubboConfigBindingBeanPostProcessor
- 只处理 Dubbo 生成的
AbstractConfig子类 Bean - 调用
DefaultDubboConfigBinder完成属性赋值
4. DefaultDubboConfigBinder
-
基于 Spring DataBinder 技术
-
把 properties 键值对绑定到 Config 对象属性
-
示例: →
ApplicationConfig.name = dubbo-demo-providerdubbo.application.name=dubbo-demo-provider
配置解析总结
Spring 环境加载 → 按前缀解析 → 生成 Config Bean → 后置处理器绑定属性值。
四、模块 2:@Service 注解解析与服务导出
核心链路
@DubboComponentScan → DubboComponentScanRegistrar → ServiceAnnotationBeanPostProcessor → DubboClassPathBeanDefinitionScanner → 生成服务实现 Bean + ServiceBean → 触发 export() 服务导出
1. DubboComponentScanRegistrar
- 注册两个核心后置处理器:
ServiceAnnotationBeanPostProcessor:处理 @ServiceReferenceAnnotationBeanPostProcessor:处理 @Reference
2. ServiceAnnotationBeanPostProcessor
- 实现
BeanDefinitionRegistryPostProcessor - 构造 DubboClassPathBeanDefinitionScanner 扫描器
3. DubboClassPathBeanDefinitionScanner
- 继承 Spring
ClassPathBeanDefinitionScanner useDefaultFilters = false:不扫描 Spring @Component,只扫 Dubbo @Service
4. 扫描后生成两个 Bean
- 服务实现类本身:普通 Spring Bean
- ServiceBean :Dubbo 服务载体,包含:
- ref:服务实现对象
- interface:服务接口
- registries:注册中心
- protocols:协议
5. 服务导出触发
ServiceBean实现ApplicationListener- Spring 启动完成 →
onApplicationEvent()→ export() → 服务暴露完成
五、模块 3:@Reference 注解解析与服务引入
核心链路
ReferenceAnnotationBeanPostProcessor → 查找 @Reference 注入点 → 生成/获取代理对象 → 完成属性注入
1. ReferenceAnnotationBeanPostProcessor
- 父类:
AnnotationInjectedBeanPostProcessor - 属于
InstantiationAwareBeanPostProcessorAdapter - 拦截 Spring 依赖注入,处理 @Reference 字段/方法
2. 注入流程
-
找到被 @Reference 标记的注入点(字段/setter)
-
计算
referencedBeanName(接口 +group+version) -
检查本地是否存在对应
ServiceBean:- 存在:直接取本地 ref 对象
- 不存在:创建远程代理
需要我把这份思维导图转成图片格式 ,或帮你生成可直接发布的公众号/博客排版文章吗?
-
生成/获取
ReferenceBean(FactoryBean) -
调用
ReferenceBean.get()得到 Dubbo 代理对象 -
反射注入到字段/方法
3. 关键缓存机制
referenceBeanCache:缓存已创建的 ReferenceBeanlocalReferenceBeanInvocationHandlerCache:缓存本地服务代理,避免重复创建
六、三大核心模块完整总结
- 配置解析 @EnableDubboConfig → 加载 properties → 生成 Config Bean → DataBinder 绑定属性
- 服务导出(@Service扫描 @Service → 生成服务实现 Bean + ServiceBean → Spring 启动完成 → export() 暴露服务
- 服务引入(@Reference扫描注入点 → 检查本地服务 → 创建/获取代理 → 完成依赖注入