dubbo源码学习(四)初始化过程细节:解析服务

2022-06-30 15:18:42 浏览数 (1)

今天将真正去看dubbo内部的实现过程,看dubbo的源码前我先把dubbo的用户指南和开发指指南大概的看了一遍,这样再看dubbo源码比较轻松。从用户指南和开发指指南可以找到相应的切入点,今天将介绍的是dubbo的初始化解析bean的过程:

解析服务

基于dubbo.jar内的META-INF/spring.handlers配置,Spring在遇到dubbo名称空间时,会回调DubboNamespaceHandler。

所有dubbo的标签,都统一用DubboBeanDefinitionParser进行解析,基于一对一属性映射,将XML标签解析为Bean对象。

在ServiceConfig.export()或ReferenceConfig.get()初始化时,将Bean对象转换URL格式,所有Bean属性转成URL的参数。

然后将URL传给Protocol扩展点,基于扩展点的Adaptive机制,根据URL的协议头,进行不同协议的服务暴露或引用。

dubbo服务的暴露调用的是:ServiceConfig.export()代码如下:

com.alibaba.dubbo.config.ServiceConfig#export

//暴露服务

public synchronized void export() {

if (provider != null) {

if (export == null) {

export = provider.getExport();

}

if (delay == null) {

delay = provider.getDelay();

}

}

if (export != null && ! export.booleanValue()) {

return;

}

if (delay != null && delay > 0) {

Thread thread = new Thread(new Runnable() {

public void run() {

try {

Thread.sleep(delay);

} catch (Throwable e) {

}

doExport();

}

});

thread.setDaemon(true);

thread.setName("DelayExportServiceThread");

thread.start();

} else {

doExport();

}

}

在查看export调用链时,可看到2个地方调用了该方法:

1、com.alibaba.dubbo.config.spring.AnnotationBean#postProcessAfterInitialization:注解的方式暴露时

2、com.alibaba.dubbo.config.spring.ServiceBean#afterPropertiesSet:以spring配置文件暴露时

AnnotationBean类的继承关系

public class AnnotationBean extends AbstractConfig implements DisposableBean, BeanFactoryPostProcessor, BeanPostProcessor, ApplicationContextAware {

AnnotationBean实现了spring bean和context相关的接口,在spring扫描完注解类,并解析完时调用 export()方法对服务进行暴露

ServiceBean

public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener, BeanNameAware {

在spring初始化解析bean完成,主要是在对spring标签的解析,bean的定义,bean的属性解析设值等完成后 进行 export()

因为dubbo是自己的自定义标签,所以对于bean的解析是 export 前最重要的部分,今天先不看服务的暴露,先看dubbo对于服务的解析,重要的两个类:

com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler

com.alibaba.dubbo.config.spring.schema.DubboBeanDefinitionParser#parse

以下为DubboNamespaceHandler代码,加上了我的注释(自己的理解)

public class DubboNamespaceHandler extends NamespaceHandlerSupport {

static {

/**

* 检索是否有重复的命名空间处理器

*/

Version.checkDuplicate(DubboNamespaceHandler.class);

}

public void init() {

/**

* 注册bean,真正负解析的是DubboBeanDefinitionParser

* DubboBeanDefinitionParser将解析所有的属性,并将属性值放入BeanDefinition

*/

registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));

registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.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 DubboBeanDefinitionParser(AnnotationBean.class, true));

}

}

所有的解析工作都在 DubboBeanDefinitionParser 中;具体可以查看DubboBeanDefinitionParser

解析的最终目的是返回 RootBeanDefinition 对象,RootBeanDefinition包含了解析出来的关于bean的所有信息,注意在bean的解析完后其实只是spring将其转化成spring内部的一种抽象的数据对象结构,bean的创建(实例化)是第一次调用 getBean 时创建的。以上是dubbo对配置文件,服务定义的解析过程。后面再写dubbo服务的暴露。

0 人点赞