千家信息网

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

发表于:2025-02-08 作者:千家信息网编辑
千家信息网最后更新 2025年02月08日,如何从源码分析Dubbo与SpringBoot整合以及进行Dubbo启动,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。在分析Refe
千家信息网最后更新 2025年02月08日如何从源码分析Dubbo与SpringBoot整合以及进行Dubbo启动

如何从源码分析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);    }

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 getServices() {
return getConfigs(getTagName(ServiceConfigBase.class));
}

最终实际调用:

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

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

再来看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 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启动问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注行业资讯频道了解更多相关知识。

0