Dubbo中基于Springboot的配置注入实现

我们知道,当我们使用springboot框架引入Dubbo的时候,只需要在启动类上加入EnableDubbo注解的时候就能够注入Dubbo相关配置,我们看下怎么实现。
如果要了解这篇文档的一些内容,需要先看下之前对Springboot配置的研究SpringBoot源码读取配置源码分析,配置优先级,加载Bean信息
当我们在引入dubbo-spring-boot-starter模块的时候,查看包下面对应的spring.factorues文件,会自动注入如下类:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.apache.dubbo.spring.boot.autoconfigure.DubboAutoConfiguration,\
org.apache.dubbo.spring.boot.autoconfigure.DubboRelaxedBindingAutoConfiguration
org.springframework.context.ApplicationListener=\
org.apache.dubbo.spring.boot.context.event.DubboConfigBeanDefinitionConflictApplicationListener,\
org.apache.dubbo.spring.boot.context.event.WelcomeLogoApplicationListener,\
org.apache.dubbo.spring.boot.context.event.AwaitingNonWebApplicationListener
org.springframework.boot.env.EnvironmentPostProcessor=\
org.apache.dubbo.spring.boot.env.DubboDefaultPropertiesEnvironmentPostProcessor
org.springframework.context.ApplicationContextInitializer=\
org.apache.dubbo.spring.boot.context.DubboApplicationContextInitializer

而这里的DubboAutoConfiguration就是实现注入的关键:

@ConditionalOnProperty(prefix = DUBBO_PREFIX, name = "enabled", matchIfMissing = true)
@Configuration
@AutoConfigureAfter(DubboRelaxedBindingAutoConfiguration.class)
@EnableConfigurationProperties(DubboConfigurationProperties.class)
@EnableDubboConfig
public class DubboAutoConfiguration implements ApplicationContextAware, BeanDefinitionRegistryPostProcessor {
	.......
}

而这里的DubboConfigurationProperties

@ConfigurationProperties(DUBBO_PREFIX)
public class DubboConfigurationProperties {

    @NestedConfigurationProperty
    private Config config = new Config();

    @NestedConfigurationProperty
    private Scan scan = new Scan();

    // Single Config Bindings
    @NestedConfigurationProperty
    private ApplicationConfig application = new ApplicationConfig();

    @NestedConfigurationProperty
    private ModuleConfig module = new ModuleConfig();

    @NestedConfigurationProperty
    private RegistryConfig registry = new RegistryConfig();

    @NestedConfigurationProperty
    private ProtocolConfig protocol = new ProtocolConfig();

    @NestedConfigurationProperty
    private MonitorConfig monitor = new MonitorConfig();

    @NestedConfigurationProperty
    private ProviderConfig provider = new ProviderConfig();

    @NestedConfigurationProperty
    private ConsumerConfig consumer = new ConsumerConfig();

    @NestedConfigurationProperty
    private ConfigCenterBean configCenter = new ConfigCenterBean();

    @NestedConfigurationProperty
    private MetadataReportConfig metadataReport = new MetadataReportConfig();

    // Multiple Config Bindings

    private Map<String, ModuleConfig> modules = new LinkedHashMap<>();

    private Map<String, RegistryConfig> registries = new LinkedHashMap<>();

    private Map<String, ProtocolConfig> protocols = new LinkedHashMap<>();

    private Map<String, MonitorConfig> monitors = new LinkedHashMap<>();

    private Map<String, ProviderConfig> providers = new LinkedHashMap<>();

    private Map<String, ConsumerConfig> consumers = new LinkedHashMap<>();

    private Map<String, ConfigCenterBean> configCenters = new LinkedHashMap<>();

    private Map<String, MetadataReportConfig> metadataReports = new LinkedHashMap<>();

这里就是对应了我们经常在spring的配置文件中配置的形如:

dubbo.registry.xxxx=aaa
dubbo.protocol.xxxx=bbb

当我们使用EnableDubbo注解的时候,其结构如下:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@EnableDubboConfig
@DubboComponentScan
public @interface EnableDubbo {
......
}

可以看到相当于是使用了EnableDubboConfigDubboComponentScan这两个注解。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Import(DubboConfigConfigurationRegistrar.class)
public @interface EnableDubboConfig {
......
}

这里如果使用EnableDubboConfig注解会向spring容器注入DubboConfigConfigurationRegistrar

public class DubboConfigConfigurationRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        registerCommonBeans(registry);
    }
}
static void registerCommonBeans(BeanDefinitionRegistry registry) {

        registerInfrastructureBean(registry, ServicePackagesHolder.BEAN_NAME, ServicePackagesHolder.class);

        registerInfrastructureBean(registry, ReferenceBeanManager.BEAN_NAME, ReferenceBeanManager.class);

        // Since 2.5.7 Register @Reference Annotation Bean Processor as an infrastructure Bean
        registerInfrastructureBean(registry, ReferenceAnnotationBeanPostProcessor.BEAN_NAME,
                ReferenceAnnotationBeanPostProcessor.class);

        // TODO Whether DubboConfigAliasPostProcessor can be removed ?
        // Since 2.7.4 [Feature] https://github.com/apache/dubbo/issues/5093
        registerInfrastructureBean(registry, DubboConfigAliasPostProcessor.BEAN_NAME,
                DubboConfigAliasPostProcessor.class);

        // Since 2.7.4 Register DubboBootstrapApplicationListener as an infrastructure Bean
        registerInfrastructureBean(registry, DubboBootstrapApplicationListener.BEAN_NAME,
                DubboBootstrapApplicationListener.class);

        // Since 2.7.6 Register DubboConfigDefaultPropertyValueBeanPostProcessor as an infrastructure Bean
        registerInfrastructureBean(registry, DubboConfigDefaultPropertyValueBeanPostProcessor.BEAN_NAME,
                DubboConfigDefaultPropertyValueBeanPostProcessor.class);

        // Dubbo config initializer
        registerInfrastructureBean(registry, DubboConfigBeanInitializer.BEAN_NAME, DubboConfigBeanInitializer.class);

        // register infra bean if not exists later
        registerInfrastructureBean(registry, DubboInfraBeanRegisterPostProcessor.BEAN_NAME, DubboInfraBeanRegisterPostProcessor.class);
    }

可以看到,这里会向spring容器注入如下bean:

  • ServicePackagesHolder
  • ReferenceBeanManager:管理ReferenceBean
  • ReferenceAnnotationBeanPostProcessor: 主要用来处理DubboReference注解
  • DubboConfigAliasPostProcessor
  • DubboBootstrapApplicationListener
  • DubboConfigDefaultPropertyValueBeanPostProcessor
  • DubboConfigBeanInitializer
  • DubboInfraBeanRegisterPostProcessor

我们通过DubboAutoConfiguration将配置文件中的配置映射到对应配置类中,而这里注入的各种类,则会利用注入的配置类将相关Server、Reference进行初始化。
比如DubboBootstrapApplicationListener:

public void onApplicationEvent(ApplicationEvent event) {
        if (isOriginalEventSource(event)) {
            if (event instanceof DubboAnnotationInitedEvent) {
                // This event will be notified at AbstractApplicationContext.registerListeners(),
                // init dubbo config beans before spring singleton beans
                applicationContext.getBean(DubboConfigBeanInitializer.BEAN_NAME, DubboConfigBeanInitializer.class);

                // All infrastructure config beans are loaded, initialize dubbo here
                DubboBootstrap.getInstance().initialize();
            } else if (event instanceof ApplicationContextEvent) {
                this.onApplicationContextEvent((ApplicationContextEvent) event);
            }
        }
    }

DubboBootstrapApplicationListener在收到DubboAnnotationInitedEvent事件后,会调用DubboBootstrap进行初始化:

public synchronized void initialize() {
        if (!initialized.compareAndSet(false, true)) {
            return;
        }
        ApplicationModel.initFrameworkExts();
        startConfigCenter();
        loadConfigsFromProps();
        checkGlobalConfigs();
        startMetadataCenter();
        initMetadataService();
    }

DubboBootstrap主要是用来启动Dubbo的,为了屏蔽各种依赖框架而单独提取出来的一个启动辅助类。
这里有很多动作,包括对配置的各种检查等。
DubboConfigBeanInitializer:

public void afterPropertiesSet() throws Exception {
        init();
    }

    private void init() {
        if (initialized.compareAndSet(false, true)) {
            configManager = ApplicationModel.getConfigManager();
            referenceBeanManager = beanFactory.getBean(ReferenceBeanManager.BEAN_NAME, ReferenceBeanManager.class);
            try {
                prepareDubboConfigBeans();
                referenceBeanManager.prepareReferenceBeans();
            } catch (Throwable e) {
                throw new FatalBeanException("Initialization dubbo config beans failed", e);
            }
        }
    }

    /**
     * Initializes there Dubbo's Config Beans before @Reference bean autowiring
     */
    private void prepareDubboConfigBeans() {
        //Make sure all these config beans are inited and registered to ConfigManager
        loadConfigBeansOfType(ApplicationConfig.class);
        loadConfigBeansOfType(ModuleConfig.class);
        loadConfigBeansOfType(RegistryConfig.class);
        loadConfigBeansOfType(ProtocolConfig.class);
        loadConfigBeansOfType(MonitorConfig.class);
        loadConfigBeansOfType(ProviderConfig.class);
        loadConfigBeansOfType(ConsumerConfig.class);
        loadConfigBeansOfType(ConfigCenterBean.class);
        loadConfigBeansOfType(MetadataReportConfig.class);
        loadConfigBeansOfType(MetricsConfig.class);
        loadConfigBeansOfType(SslConfig.class);
    }

    private void loadConfigBeansOfType(Class<? extends AbstractConfig> configClass) {
        String[] beanNames = beanFactory.getBeanNamesForType(configClass, true, false);
        for (String beanName : beanNames) {
            AbstractConfig configBean = beanFactory.getBean(beanName, configClass);
            configManager.addConfig(configBean);
        }
    }

DubboConfigBeanInitializer将各种配置都注入到了ConfigManager中,然后会通过ReferenceBeanManagerReferenceBean进行初始化:

public void prepareReferenceBeans() throws Exception {
        initialized = true;
        for (ReferenceBean referenceBean : getReferences()) {
            initReferenceBean(referenceBean);
        }
}

这样就能够获取到我们注入的配置。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SpringBoot工具类使用Dubbo,首先需要确保已经完成了DubboSpringBoot的集成配置。在SpringBoot配置文件,需要设置Dubbo的相关配置,如application.id、application.name、registry.address、server等等。\[1\] 接下来,在工具类所在的包添加Dubbo的依赖项。可以在pom.xml文件添加以下依赖项: ```xml <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>3.1.0</version> </dependency> ``` 这样就可以引入Dubbo的Spring Boot Starter,以便在Spring Boot应用使用Dubbo功能。\[2\] 然后,在Spring Boot的启动类上添加@EnableDubboConfiguration注解,以启用Dubbo配置。同时,可以使用@MapperScan注解指定Dubbo的DAO包路径,以便自动扫描并注入Dubbo的Mapper接口。示例代码如下: ```java @MapperScan("com.xq.live.dubbo.dao") @EnableDubboConfiguration @SpringBootApplication public class DubboServerApplication { public static void main(String\[\] args) { SpringApplication.run(DubboServerApplication.class, args); } } ``` 这样就完成了在Spring Boot工具类使用Dubbo配置。可以在工具类注入Dubbo的服务接口,并调用相应的方法来实现业务逻辑。 #### 引用[.reference_title] - *1* *3* [dubbospringboot的集成和使用dubbo-spring-boot-starter](https://blog.csdn.net/m0_67393295/article/details/126648167)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [dubbo教程总结(springboot+dubbo)](https://blog.csdn.net/black_pp/article/details/128102018)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值