12. Dubbo服务暴露入口及源码更改
1. 开篇
从前面几篇文章中,我们已经了解到Dubbo服务的注解的解析已经对应Bean的生成,既然该准备的都已经准备好了,接下来就该暴露服务,提供服务了。
一说到Dubbo
的服务暴露,我们或多或少的知道服务暴露的入口是在ServiceBean
类里的export
方法(父类里),或者说是ServiceConfig
类里的export
,那么具体是从什么地方调用到这个方法呢?
在我使用的版本(2.7.15)中最初始的导出入口位于DubboBootstrap#start
方法中。
本文主要介绍Spring
容器启动后,是如何调用到服务暴露的方法的。
我们知道在Spring
启动完成后,会进行事件的发布,Dubbo
与Spring
集成时,就是先向Spring
容器中注册一个监听器,即DubboBootstrapApplicationListener
,来监听Spring
的事件,等启动成功后,就开始Dubbo
服务的具体处理工作。
那是什么时候向Spring
容器中注册的呢?其实注册的入口有两个,个人感觉可以合成一个,这个在文本结尾源码修改
处进行介绍。
2. 注册入口一
第一个注册入口是在解析@DubboService
注解的时候,在解析@DubboService
注解时,会向Spring
容器里注册一个Bean
:ServiceClassPostProcessor
,在这个类中就会注册一个Dubbo
的监听器。
3. 注册入口二
第二个入口是在解析@DubboReference
注解的时候,调用registerCommonBeans
方法的时候,向Spring容器注册了一个类DubboApplicationListenerRegistrar
。
registerInfrastructureBean(registry, DubboApplicationListenerRegistrar.BEAN_NAME,
DubboApplicationListenerRegistrar.class);
DubboApplicationListenerRegistrar
这个类实现类ApplicationContextAware
接口,在注入ApplicationContext
的时候初始化了监听。不过,这里的初始化Dubbo的监听是通过new
创建出来的。
4. Dubbo监听器
Dubbo的监听器类为DubboBootstrapApplicationListener
,这个类继承了OnceApplicationContextEventListener
,实现了onApplicationContextEvent
方法,这个方法会在Spring发布事件的时候被调用。Dubbo监听器接收到Spring容器刷新的监听事件后,就会执行dubboBootstrap.start()
。
dubboBootstrap
是在DubboBootstrapApplicationListener
实例化时,从构造方法中赋值的。下面来看下dubboBootstrap
的start
方法。
看到这里我们就明白了,exportServices
这个方法就是用来进行服务导出的,在这个方法内会循环遍历每一个ServiceBean
然后再调用其export
方法进行导出。
5. 源码改造
上面说了,注册Dubbo监听器有两个入口,个人感觉是可以复用的,下面就对源码进行一些更改看是否可以正常运行。
5.1 更改方法一
更改的方法为ServiceClassPostProcessor#postProcessBeanDefinitionRegistry
,既然再解析@DubboReference
注解的时候会进行new初始化,那这里是不是可以直接去掉?下面代码为注释后的样子。
5.2 更改方法二
与方法一是反过来的,我是不是不用直接new初始化,直接从Spring容器里获取Dubbo的监听器呢?下面代码为从Spring容器里获取的样子。
5.3 更改验证
经过运行验证发现是可以正常使用的,不过也可能跟运行Demo项目太过简单有关系,对于复杂的项目是否会产生影响还是个未知数。
6. 后记
本文介绍了Dubbo
服务暴露的入口,以及对Dubbo
监听器注册的源码的地方进行了一点改动,这个改动仅限于个人观点,既然这样写可能也有一定的作用,是不是?如有不同意见欢迎讨论。
作者:Java星辰 链接:https://juejin.cn/post/7175322757923045413