鉴于大多数人使用dubbo都是在spring环境下的,所以我们优先看依赖spring的dubbo是怎么启动的. 在了解dubbo真正开始启动之前,还有一些初始化的工作要做.
我们从最原始的xml的配置方式看起,虽然现在这种方式随着springboot的兴起已经不是很常见了,但是还是会有不少企业或者遗留项目在使用,而且xml的配置方式算是原理级的了,了解总是没有坏处的.
开始之前
在开始之前我们先看下我们的demo的一些重要配置.
pom.xml
<profiles>
<!-- For jdk 11 above JavaEE annotation -->
<profile>
<id>javax.annotation</id>
<activation>
<jdk>[1.11,)</jdk>
</activation>
<dependencies>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
</dependencies>
</profile>
</profiles>
因为使用的是jdk11而jdk11移除 JavaEE 和 CORBA 模块,JavaFX 也已被移除,所以想要@PostConstruct注解生效需要添加上边的profile,否则启动失败.
No application config found or it's not a valid config! Please add <dubbo:application name="..." /> to your spring config.
spring.xml
<dubbo:application name="dubbo-provider-sample"/>
<!-- 使用multicast广播注册中心暴露服务地址 -->
<dubbo:registry address="multicast://224.5.6.7:1234" register="false"/>
<dubbo:protocol name="dubbo"/>
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="li.dongpo.tc.SampleService"
ref="sampleServiceImpl" />
DubboNamespaceHandler
dubbo的配置有专用的标签<dubbo>,spring提供自定义标签的方式就是NamespaceHandler,通过实现NamespaceHandler接口的方式可以自定义标签.
关于自定义标签的部分就不展开了,网上资料非常多,而且现在都是springboot了这种方式也不常见了.
简单来说,DubboNamespaceHandler就是用来解析spring配置文件中<dubbo:xxxx/>这类标签的,每个dubbo标签根据xxxx的不同注入不同的bean,每行配置类似于springboot中的一个@Bean注解.
registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
registerBeanDefinitionParser("config-center", new DubboBeanDefinitionParser(ConfigCenterBean.class, true));
registerBeanDefinitionParser("metadata-report", new DubboBeanDefinitionParser(MetadataReportConfig.class, true));
registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
registerBeanDefinitionParser("metrics", new DubboBeanDefinitionParser(MetricsConfig.class, true));
registerBeanDefinitionParser("ssl", new DubboBeanDefinitionParser(SslConfig.class, true));
registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
registerBeanDefinitionParser("annotation", new AnnotationBeanDefinitionParser());
关于这个配置可以参见 dubbo-基础用法-provider-配置
所以xml中的配置 <dubbo:application name=“dubbo-provider-sample”/> 就开始生效了,注入了一个ApplicationConfig. 需要注意的是ApplicationConfig是AbstractConfig的一个子类,而AbstractConfig中包含@PostConstruct注解,所以在注入的时候会执行ApplicationModel.getConfigManager().addConfig(this) 下边的RegistryConfig也是一样的.
ApplicationModel.getConfigManager()这行开始执行的时候,dubbo的扩展机制(ExtensionLoader)就开始初始化了. 这个扩展机制比较重要我们后续展开说.