Spring与Dubbo整合的整体流程(基于apache-dubbo-2.7.15)
因为dubbo有较多的兼容以前的代码比如@DubboReference 以前就有两个版本@Reference 和@com.alibaba.dubbo.config.annotation.Reference ,为了方便文章如果提到@DubboReference其实可能还包括的其他两个注解,其他情况也类似。
- Spring启动时先根据properties配置生成9个Config对象,如应用配置,注册中心配置等。
- Spirng 与Dubbo整合主要是理解dubbo是如何利用spring提供的扩展点来处理
@DubboService
和@DubboReference
- 扫描
@DubboService
是会生成两个spring bean 。ServiceBean
和服务提供者的实际逻辑处理类(如DemoServiceImpl
)。ServiceBean通过变量ref进行引用。
spring整合dubbo启动和配置
public class Application {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ProviderConfiguration.class);
context.start();
System.in.read();
}
@Configuration
@EnableDubbo(scanBasePackages = "org.apache.dubbo.demo.provider")
@PropertySource("classpath:/spring/dubbo-provider.properties")
static class ProviderConfiguration {
@Bean
public RegistryConfig registryConfig() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress("zookeeper://127.0.0.1:2181");
return registryConfig;
}
}
}
应⽤配置类为ProviderConfiguration
, 在配置上有两个⽐较重要的注解
@PropertySource
表示将dubbo-provider.properties
中的配置项添加到Spring容器中,可以通过
@Value的⽅式获取到配置项中的值。@EnableDubbo(scanBasePackages = "org.apache.dubbo.demo.provider")
表示对指定包下的类
进⾏扫描,扫描@DubboService与
@DubboReference
注解,并且进⾏处理。
在EnableDubbo
注解上,有另外两个注解,也是研究Dubbo最重要的两个注解
1.@EnableDubboConfig
2.@DubboComponentScan
@Target({
ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Import(DubboConfigConfigurationRegistrar.class)
public @interface EnableDubboConfig {
boolean multiple() default true;
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(DubboComponentScanRegistrar.class)
public @interface DubboComponentScan {
String[] value() default {
};
String[] basePackages() default {
};
Class<?>[] basePackageClasses() default {
};
}
注意两个注解中对应的@Import
注解所导⼊的类:
DubboConfigConfigurationRegistrar
DubboComponentScanRegistrar
Spring在启动时会解析这两个注解,并且执⾏对应的Registrar类中的registerBeanDefinitions
⽅法(这
是Spring中提供的扩展功能。)
EnableDubboConfig
Single和Multiple
public class DubboConfigConfigurationRegistrar implements ImportBeanDefinitionRegistrar, ApplicationContextAware {
private ConfigurableApplicationContext applicationContext;
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AnnotationAttributes attributes = AnnotationAttributes.fromMap(
importingClassMetadata.getAnnotationAttributes(EnableDubboConfig.class.getName()));
boolean multiple = attributes.getBoolean("multiple");
// Single Config Bindings
registerBeans(registry, DubboConfigConfiguration.Single.class);
if (multiple) {
// Since 2.6.6 https://github.com/apache/dubbo/issues/3193
registerBeans(registry, DubboConfigConfiguration.Multiple.class);
}
// Since 2.7.6
registerCommonBeans(registry);
}
....省略
}
registerBeanDefinitions
方法调用registerBeans
向spring容器注册了DubboConfigConfiguration.Single.class
和DubboConfigConfiguration.Multiple.class
两个BeanDefinition
。
public class DubboConfigConfiguration {
/**
* Single Dubbo {@link AbstractConfig Config} Bean Binding
*/
@EnableConfigurationBeanBindings({
@EnableConfigurationBeanBinding(prefix = "dubbo.application", type = ApplicationConfig.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.module", type = ModuleConfig.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.registry", type = RegistryConfig.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.protocol", type = ProtocolConfig.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.monitor", type = MonitorConfig.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.provider", type = ProviderConfig.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.consumer", type = ConsumerConfig.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.config-center", type = ConfigCenterBean.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.metadata-report", type = MetadataReportConfig.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.metrics", type = MetricsConfig.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.ssl", type = SslConfig.class)
})
public static class Single {
}
/**
* Multiple Dubbo {@link AbstractConfig Config} Bean Binding
*/
@EnableConfigurationBeanBindings({
@EnableConfigurationBeanBinding(prefix = "dubbo.applications", type = ApplicationConfig.class, multiple = true),
@EnableConfigurationBeanBinding(prefix = "dubbo.modules", type = ModuleConfig.class, multiple = true),
@EnableConfigurationBeanBinding(prefix = "dubbo.registries", type = RegistryConfig.class, multiple = true),
@EnableConfigurationBeanBinding(prefix = "dubbo.protocols", type = ProtocolConfig.class, multiple = true),
@EnableConfigurationBeanBinding(prefix = "dubbo.monitors", type = MonitorConfig.class, multiple = true),
@EnableConfigurationBeanBinding(prefix = "dubbo.providers"