Dubbo源码|十二、Dubbo服务暴露入口及其源码更改

301 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第16天,点击查看活动详情

开篇

从前面几篇文章中,我们已经了解到Dubbo服务的注解的解析已经对应Bean的生成,既然该准备的都已经准备好了,接下来就该暴露服务,提供服务了。

一说到Dubbo的服务暴露,我们或多或少的知道服务暴露的入口是在ServiceBean类里的export方法(父类里),或者说是ServiceConfig类里的export,那么具体是从什么地方调用到这个方法呢?

在我使用的版本(2.7.15)中最初始的导出入口位于DubboBootstrap#start方法中。

本文主要介绍Spring容器启动后,是如何调用到服务暴露的方法的。

我们知道在Spring启动完成后,会进行事件的发布,DubboSpring集成时,就是先向Spring容器中注册一个监听器,即DubboBootstrapApplicationListener,来监听Spring的事件,等启动成功后,就开始Dubbo服务的具体处理工作。

那是什么时候向Spring容器中注册的呢?其实注册的入口有两个,个人感觉可以合成一个,这个在文本结尾源码修改处进行介绍。

注册入口一

第一个注册入口是在解析@DubboService注解的时候,在解析@DubboService注解时,会向Spring容器里注册一个BeanServiceClassPostProcessor,在这个类中就会注册一个Dubbo的监听器。

image.png

注册入口二

第二个入口是在解析@DubboReference注解的时候,调用registerCommonBeans方法的时候,向Spring容器注册了一个类DubboApplicationListenerRegistrar

registerInfrastructureBean(registry, DubboApplicationListenerRegistrar.BEAN_NAME,
        DubboApplicationListenerRegistrar.class);

DubboApplicationListenerRegistrar这个类实现类ApplicationContextAware接口,在注入ApplicationContext的时候初始化了监听。不过,这里的初始化Dubbo的监听是通过new创建出来的。

image.png

Dubbo监听器

Dubbo的监听器类为DubboBootstrapApplicationListener,这个类继承了OnceApplicationContextEventListener,实现了onApplicationContextEvent方法,这个方法会在Spring发布事件的时候被调用。Dubbo监听器接收到Spring容器刷新的监听事件后,就会执行dubboBootstrap.start()

image.png

dubboBootstrap是在DubboBootstrapApplicationListener实例化时,从构造方法中赋值的。下面来看下dubboBootstrapstart方法。

image.png

看到这里我们就明白了,exportServices这个方法就是用来进行服务导出的,在这个方法内会循环遍历每一个ServiceBean然后再调用其export方法进行导出。

源码改造

上面说了,注册Dubbo监听器有两个入口,个人感觉是可以复用的,下面就对源码进行一些更改看是否可以正常运行。

更改方法一

更改的方法为ServiceClassPostProcessor#postProcessBeanDefinitionRegistry,既然再解析@DubboReference注解的时候会进行new初始化,那这里是不是可以直接去掉?下面代码为注释后的样子。

image.png

更改方法二

与方法一是反过来的,我是不是不用直接new初始化,直接从Spring容器里获取Dubbo的监听器呢?下面代码为从Spring容器里获取的样子。

image.png

更改验证

经过运行验证发现是可以正常使用的,不过也可能跟运行Demo项目太过简单有关系,对于复杂的项目是否会产生影响还是个未知数。

后记

本文介绍了Dubbo服务暴露的入口,以及对Dubbo监听器注册的源码的地方进行了一点改动,这个改动仅限于个人观点,既然这样写可能也有一定的作用,是不是?如有不同意见欢迎讨论。