dubbo啟動腳本
⑴ bbo是如何啟動的
已知,在項目啟動過程中,我們會將bbo的配置文件寫到spring的配置文件里,如下xml文件:
<bbo:application name="anyname_provider" />
<!-- 使用zookeeper注冊中心暴露服務地址 -->
<bbo:registry address="zookeeper://127.0.0.1:2181" />
<!-- 用bbo協議在20880埠暴露服務 -->
<bbo:protocol name="bbo" port="20880" />
<!-- 聲明需要暴露的服務介面 -->
<bbo:service interface="com.shxz130.provider.Provider"
ref="demoService" />
從官方文檔中,我們能看到如下:
啟動過程.png
也就是說spring啟動過程中,隨著Spring在初始化過程中,碰到bbo命名的標簽,如(<bbo:service>,<bbo:registry>)等標簽,會由DubboNamespaceHandler類處理,具體原理見鏈接Spring自定義標簽
DubboBeanDefinitionParser代碼如下:
public class DubboNamespaceHandler extends NamespaceHandlerSupport { static {
Version.checkDuplicate(DubboNamespaceHandler.class);
} public void init() {
registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
registerBeanDefinitionParser("mole", new DubboBeanDefinitionParser(MoleConfig.class, true));
registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.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 ());
}
}
遇到不同的標簽,會由不同的Parser處理,這里重點看服務發布,這行代碼:
registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
也就是說,當Spring容器處理完<bbo:service>標簽後,會在Spring容器中生成一個ServiceBean ,服務的發布也會在ServiceBean中完成。不妨看一下ServiceBean的定義:
public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener<ContextRefreshedEvent>, BeanNameAware {
}
該Bean實現了很多介面,關於InitializingBean,DisposableBean,ApplicationContextAware,BeanNameAware,這些介面的使用介紹如下鏈接:
InitializingBean&DisposableBean
BeanNameAware& ApplicationContextAware
- public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener<ContextRefreshedEvent>, BeanNameAware { //Spring容器初始化完成,調用
- public void onApplicationEvent(ContextRefreshedEvent event) { if (isDelay() && !isExported() && !isUnexported()) { if (logger.isInfoEnabled()) {
- logger.info("The service ready on spring started. service: " + getInterface());
- } //暴露服務
- export();
- }
- } //判斷是否延遲發布
- private boolean isDelay() {
- Integer delay = getDelay();
- ProviderConfig provider = getProvider(); if (delay == null && provider != null) {
- delay = provider.getDelay();
- } return supportedApplicationListener && (delay == null || delay == -1);
- } //當bean初始化完成調用
- public void afterPropertiesSet() throws Exception { //......此處省略10000行代碼
- if (!isDelay()) { //暴露服務
- export();
- }
- }
- }
- public synchronized void export() { //忽略若干行代碼
- if (delay != null && delay > 0) { //當delay不為null,且大於0時,延遲delay時間,暴露服務
- delayExportExecutor.schele(new Runnable() { public void run() { //暴露服務
- doExport();
- }
- }, delay, TimeUnit.MILLISECONDS);
- } else { //直接暴露服務
- doExport();
- }
- }
- protected synchronized void doExport() { //忽略10000行代碼
- doExportUrls(); //忽略10000行代碼
- } private void doExportUrls() {
- List<URL> registryURLs = loadRegistries(true); for (ProtocolConfig protocolConfig : protocols) { //按照不同的Protocal暴露服務
- doExportUrlsFor1Protocol(protocolConfig, registryURLs);
- }
- }
而在Spring初始化完成Bean的組裝,會調用InitializingBean的afterPropertiesSet方法,在Spring容器載入完成,會接收到事件ContextRefreshedEvent,調用ApplicationListener的onApplicationEvent方法。
在afterPropertiesSet中,和onApplicationEvent中,會調用export(),在export()中,會暴露bbo服務,具體區別在於是否配置了delay屬性,是否延遲暴露,如果delay不為null,或者不為-1時,會在afterPropertiesSet中調用export()暴露bbo服務,如果為null,或者為-1時,會在Spring容器初始化完成,接收到ContextRefreshedEvent事件,調用onApplicationEvent,暴露bbo服務。
部分ServiceBean的代碼如下:
在export(),暴露服務過程中,如果發現有delay屬性,則延遲delay時間,暴露服務,如果沒有,則直接暴露服務。
而在doExport()中,驗證參數,按照不同的Protocol,比如(bbo,injvm)暴露服務,在不同的zookeeper集群節點上注冊自己的服務。
作者:一滴水的堅持
鏈接:https://www.jianshu.com/p/7f3871492c71
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並註明出處。