栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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 modules = new linkedHashMap<>();

    private Map registries = new linkedHashMap<>();

    private Map protocols = new linkedHashMap<>();

    private Map monitors = new linkedHashMap<>();

    private Map providers = new linkedHashMap<>();

    private Map consumers = new linkedHashMap<>();

    private Map configCenters = new linkedHashMap<>();

    private Map 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 {
......
}

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

@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);
            }
        }
    }

    
    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 configClass) {
        String[] beanNames = beanFactory.getBeanNamesForType(configClass, true, false);
        for (String beanName : beanNames) {
            AbstractConfig configBean = beanFactory.getBean(beanName, configClass);
            configManager.addConfig(configBean);
        }
    }

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

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

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/530962.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号