前言
Dubbo3.0有很多新的类(较2.0来说),本文主要就3.0中DubboBootstrap及其相关的类进行讲解,主要为想了解Dubbo3.0启动模型的同学做参考。
版本说明
Dubbo版本:3.0.9
DubboBootstrap的组成部分
DubboBootstrap的关键属性有4个,分别是ApplicationModel、ConfigManager、Environment、ApplicationDeployer。他们功能分别是应用的定义(可以理解为领域对象中的Entity)、配置管理、环境变量管理、应用声明周期管理。
ApplicationModel讲解
讲到ApplicationModel就不得不提到Dubbo的另外两个领域模型FrameworkModel和ModuleModel。
模型之间的依赖关系
这三个模型紧密相连,整个Dubbo共用一个FrameworkModel,一个FrameworkModel中允许有多个ApplicationModel存在,同时在一个ApplicationModel里面又允许有多个ModuleModel同时存在。同时,ApplicationModel又保留FrameworkModel的引用,ModuleModel也保留了ApplicationModel的引用。(也就是说FrameworkModel和ApplicationModel之间保持了双向引用,ApplicationModel和ModuleModel之间也保持了双向引用)
模型共有的特性
这三个模型都集成自ScopeModel,其中我想重点讲的是classLoaders、extensionScope、extensionDirector这三个。
- 每个Model其实都有自己的classLoader,他们都通过自己的classLoader来加载类(在没有特殊指定的情况下默认是使用AppClassLoader)
- extensionScope和extensionDirector配合使用来控制SPI扩展点的的实例(ExtensionLoader)。ExtensionLoader现在不是全局单例的,而是在ExtensionScope维度下是单例的(可以理解是按照ExtensionScope维度对SPI扩展点的加载做了隔离,不能跨scope获取SPI实例)。
模型的差别
这三个模型大致功能相同,不同的点在于功能维度不同。FrameworkModel主要提供的是已经暴露过的Provider信息的查询。ApplicationModel和ModuleModel的差别主要体现在Environment、ServiceRepository、ConfigManager、Deployer上。
- ApplicationModel中可以查询整个应用的配置、环境变量,以及应用的初始化。
- ModuleModel中只能查当前进程里面的相关应用配置、环境变量,同时他的ModuleModel也只负责服务的暴露和引用。
ConfigManager讲解
Config和Environment是有差别的,前者代表的是写在应用内的配置(可以理解为必须要的配置,比如:想要应用启动那一定要配置registry的配置,想要暴露一个服务就必须定义一个ServiceConfig),后者代表外部化配置(可以理解为一个值的获取方式,比如:RegistryConfig的地址是${spring.zookeeper.url},而它的取值方式可以是多种多样的,从spring、环境变量、JVM变量等等。我们可以通过这种方式,让部分属性值做到根据不同环境来设置不同的值) Dubbo将配置做了抽象,比如:ProtocolConfig、RegistryConfig、ReferenceConfig、ServiceConfig、ApplicationConfig等等。每个Config代表的是Dubbo的配置,比如:注册中心的配置在RegistryConfig中、服务暴露的配置在ServiceConfig中等等。当然也没什么说的,这个类主要是提供配置的查询功能,唯一要注意的是ModuleConfigManager和ConfigManager其实就是能加载的配置不一样(在各自构造函数中限制了能加载那些配置)。
Environment讲解
Dubbo的环境变量有几种来源方式,比如:系统环境变量、Spring环境变量。详情可以参考小马哥的文章
ApplicationDeployer讲解
ApplicationDeployer和ModuleDeployer两个类的创建都需要Model(ApplicationDeployer的创建需要ApplicationModel,ModuleDeployer的创建需要ModuleModel),而我们知道Model是有双向引用的,因此这两个Deployer可以通过Model互通。
在DubboBootstrap中我们也能看到这两个类的互调,比如:org.apache.dubbo.config.deploy.DefaultApplicationDeployer#start
-> org.apache.dubbo.config.deploy.DefaultApplicationDeployer#doStart
-> org.apache.dubbo.config.deploy.DefaultApplicationDeployer#startModules
通过这个调用链我们可以看到ApplicationDeployer调用ModuleDeployer,org.apache.dubbo.config.deploy.DefaultModuleDeployer#start
我们从这个方法里面也能看到很多ApplicationDeployer的身影。
两个Deployer的差别
- ApplicationDeployer负责应用的启动和初始化,ModuleDeployer负责服务的暴露和引用。 这两个类的差别其实就是功能上的差别,其他的都是由于功能差别导致的(比如内部属性的差异、接口的差异,这些其实都是由他们的职责差异导致的)。