温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何从源码分析Dubbo与SpringBoot整合以及进行Dubbo启动

发布时间:2021-09-29 16:01:34 来源:亿速云 阅读:123 作者:柒染 栏目:云计算

如何从源码分析Dubbo与SpringBoot整合以及进行Dubbo启动,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

在分析Reference是提到过Dubbo会自动引配置类,这里需要注意DubboBootstrapApplicationListener:

registerCommonBeans(BeanDefinitionRegistry registry) {
        registerInfrastructureBean(registry, ReferenceAnnotationBeanPostProcessor.BEAN_NAME,
                ReferenceAnnotationBeanPostProcessor.class);
        registerInfrastructureBean(registry, DubboConfigAliasPostProcessor.BEAN_NAME,
                DubboConfigAliasPostProcessor.class);
        registerInfrastructureBean(registry, DubboLifecycleComponentApplicationListener.BEAN_NAME,
                DubboLifecycleComponentApplicationListener.class);
        registerInfrastructureBean(registry, DubboBootstrapApplicationListener.BEAN_NAME,
                DubboBootstrapApplicationListener.class);
        registerInfrastructureBean(registry, DubboConfigDefaultPropertyValueBeanPostProcessor.BEAN_NAME,
                DubboConfigDefaultPropertyValueBeanPostProcessor.class);
    }

如何从源码分析Dubbo与SpringBoot整合以及进行Dubbo启动

public class DubboBootstrapApplicationListener extends OneTimeExecutionApplicationContextEventListener
        implements Ordered {
private final DubboBootstrap dubboBootstrap;

    public DubboBootstrapApplicationListener() {
        //这里是一个单例
        this.dubboBootstrap = DubboBootstrap.getInstance();
    }
//监听事件
    @Override
    public void onApplicationContextEvent(ApplicationContextEvent event) {
        if (event instanceof ContextRefreshedEvent) {
            onContextRefreshedEvent((ContextRefreshedEvent) event);//上下文刷新完成事件
        } else if (event instanceof ContextClosedEvent) {
            onContextClosedEvent((ContextClosedEvent) event);//关闭事件
        }
    }

    private void onContextRefreshedEvent(ContextRefreshedEvent event) {
        dubboBootstrap.start();
    }

    private void onContextClosedEvent(ContextClosedEvent event) {
        dubboBootstrap.stop();
    }
}

DubboBootstrapApplicationListener 实现了Spring的事件监听,当上下文刷新完成的时候,会执行dubboBootstrap.start():

public DubboBootstrap start() {
        //CAS
        if (started.compareAndSet(false, true)) {
            ready.set(false);
            //初始化
            initialize();        
            //Dubbo服务导出
            exportServices();
            if (!isOnlyRegisterProvider() || hasExportedServices()) {
                exportMetadataService();
                registerServiceInstance();
            }

            //服务引用
            referServices();
        }
        return this;
    }

先看exportServices()服务导出:

private void exportServices() {
        configManager.getServices().forEach(sc -> {
            ServiceConfig serviceConfig = (ServiceConfig) sc;
            serviceConfig.setBootstrap(this);

            if (exportAsync) {
                ExecutorService executor = executorRepository.getServiceExporterExecutor();
                Future<?> future = executor.submit(() -> {
                    sc.export();
                    exportedServices.add(sc);
                });
                asyncExportingFutures.add(future);
            } else {
                sc.export();
                exportedServices.add(sc);
            }
        });
    }

循环configManager.getServices()中的数据依次执行导出,那这些Service是从哪来的?:

public Collection<ServiceConfigBase> getServices() {
        return getConfigs(getTagName(ServiceConfigBase.class));
    }

最终实际调用:

protected <C extends AbstractConfig> Map<String, C> getConfigsMap(String configType) {
        return (Map<String, C>) read(() -> configsCache.getOrDefault(configType, emptyMap()));
    }

getTagName(ServiceConfigBase.class) 获取类的标签,这里也就是service。我们之前分析过Dubbo的DubboService注解在注册原始类的同时还会注册ServiceBean。下面看ServiceBean的类结构图, 它是ServiceConfigBase的一个子类,那么他是如何放到configsCache中去的?

如何从源码分析Dubbo与SpringBoot整合以及进行Dubbo启动

再来看ServiceConfigBase的父类AbstractConfig,它里面有一个PostConstruct注解的方法,查看官方解释:PostConstruct注解用于需要依赖注入完成以执行任何初始化之后要执行的方法上。必须在类投入使用之前调用此方法。所有支持依赖注入的类都必须支持该注释。即使该类不要求注入任何资源,也必须调用用PostConstruct注释的方法。也就是说所有的ServiceBean在被Spring初始化之后都会调用addIntoConfigManager方法。

@PostConstruct
    public void addIntoConfigManager() {
        ApplicationModel.getConfigManager().addConfig(this);
    }

addIntoConfigManager方法的实际作用就是向configsCache中缓存:

protected void addConfig(AbstractConfig config, boolean unique) {
        if (config == null) {
            return;
        }
        write(() -> {
            Map<String, AbstractConfig> configsMap = configsCache.computeIfAbsent(getTagName(config.getClass()), type -> newMap());
            addIfAbsent(config, configsMap, unique);
        });
    }

所以,Dubbo中凡是实现AbstractConfig接口的类,在被Spring初始化之后,最终都会被缓存到configManager中。

总结:

1、Dubbo中实现AbstractConfig接口的Bean,在被Spring初始化之后,都会被放入configManager。

2、Dubbo通过实现Spring的监听事件,在上下文刷新完成的时候开始进行Dubbo服务的初始化和启动。

3、启动引导类dubboBootstrap 是一个单例。

至此,Dubbo容器的启动分析完成。

关于如何从源码分析Dubbo与SpringBoot整合以及进行Dubbo启动问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI