DubboBootstrapApplicationListener
既然是在基于spring,那么启动的引导就那几个花样,dubbo使用的是实现ApplicationListener接口的方式(注意是2.7.6,其他版本可能不一样).
先看构造方法: 在DubboBootstrapApplicationListener的构造方法中,只做了一件事,就是初始化DubboBootstrap,调用的是DubboBootstrap.getInstance(),这个getInstance里是经典的两次判空实现单例,略过不谈.
OneTimeExecutionApplicationContextEventListener实现了ApplicationListener,提供了抽象方法onApplicationContextEvent来处理spring的事件.
DubboBootstrapApplicationListener是OneTimeExecutionApplicationContextEventListener的一个子类,onApplicationContextEvent的具体逻辑就是在这里实现的.
onApplicationContextEvent
可以看到onApplicationContextEvent中处理了两种事件,ContextRefreshedEvent和ContextClosedEvent,分别对应onContextRefreshedEvent方法和onContextClosedEvent方法.
onContextRefreshedEvent方法和onContextClosedEvent方法的具体逻辑也比较简单,就是调用了DubboBootstrap的start和stop方法.
DubboBootstrap
上边说了半天,其实就是dubbo启动的引导,也就是调用dubbo的启动入口,DubboBootstrap才是真正的启动实现,真正复杂的也在这里边.
还是先看构造方法,做了下边几件事:
- 初始化了一个 ConfigManager ❶
- 初始化了一个 Environment ❷
- 注册了一个DubboShutdownHook,shutdown的时候调用DubboBootstrap的destroy()方法
start()
上边说了,启动收到ContextRefreshedEvent事件的时候启动dubbo,启动就是执行这个方法,这才是dubbo启动的核心入口.
这里边做了几件事:
- initialize(); 看起来像是初始化的一些逻辑,一会深究
- exportServices(); 看起来像是注册Provider的入口 ❸
- exportMetadataService(); registerServiceInstance(); 2.7.8之后才有的逻辑,先跳过,不影响主逻辑
- referServices(); 看起来像是注入consumer的bean ❹
- awaitFinish(); 等待asyncExportingFutures初始化完成,这个看起来也不影响主逻辑的理解,先跳过吧.
initialize()
这里边做了几件事:
- ApplicationModel.initFrameworkExts(); 初始化所有FrameworkExt,其实就是SPI形式的Lifecycle
- startConfigCenter(); dubbo的配置中心模块,后续我们深入研究 ❺
- loadRemoteConfigs();
- checkGlobalConfigs();
- startMetadataCenter();
- initMetadataService();
- initMetadataServiceExports();
- initEventListener();
至此其实dubbo启动的主逻辑就差不多了,剩下的就是丰富里边的细节了.
TODO
留几个flag,后面一个一个啃
❶ ConfigManager初始化的时候用到了Extension逻辑,其实就是dubbo的SPI机制,这块比较复杂之后详细研究
❷ 和❶一样
❸ Provider的注册逻辑,比较复杂后续展开说
❹ Consumer的注入逻辑,比较复杂后续展开说
❺ 看起来SPI机制了解了之后就得研究配置模块了