如何从源码分析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<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中去的?
再来看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启动问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。