前言
有了上一篇的Dubbo消费者初始化过程的经验,接着来看生产者初始化的过程应该会简单不少,马上进入正题。
源码
有了上一次找初始化入口ReferenceBean
类的经验,这次很快就找到了对应的入口ServiceBean
类,我们来看一下它的类结构
1 | public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener, BeanNameAware |
是不是很熟悉,那么直接来看afterPropertiesSet
方法
1 | public void afterPropertiesSet() throws Exception { |
这里前面一大段都是在做初始化的准备工作,真正开始进行初始化的是最后的export()
方法。当然,这里有一个前提就是要满足条件! isDelay()
1 | private boolean isDelay() { |
很明显这个方法是用来控制服务是否延迟加载的,由于初始化supportedApplicationListener
值就为true,因此delay
默认不配时就是开启延迟加载,也就是暂不调用export()
方法,那么这个方法会在哪里调用呢?答案是onApplicationEvent(ApplicationEvent event)
1 | public void onApplicationEvent(ApplicationEvent event) { |
这也是Spring中的熟面孔了,这里它监听的是ContextRefreshedEvent
,当监听到刷新事件并满足isDelay() && ! isExported() && ! isUnexported()
条件时,才正式调用export()
方法
1 | public synchronized void export() { |
这里主要是启动了一个守护线程来做延迟加载,实现还是调用了doExport()
方法
1 | protected synchronized void doExport() { |
省略了一下初始化配置的代码,剩下checkApplication()
、checkRegistry()
和checkProtocol()
方法都是配置项的检查,appendProperties(AbstractConfig config)
方法上一篇消费者初始化中也分析过了就是初始化执行传入对象的set方法,这里就都不做过多分析了,重点来看一下doExportUrls()
方法
1 | private void doExportUrls() { |
loadRegistries(true)
方法上次也分析过了,用于获取注册中心的信息,那么继续跟doExportUrlsFor1Protocol(protocolConfig, registryURLs)
方法
1 | private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) { |
方法比较长,在上面一些不是很重要的部分我标了一些注释,就不深入讲了,重点来看一下下面这段
1 | Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.toFullString())); |
proxyFactory.getInvoker
的具体实现就不重复讲了,直接来看JavassistProxyFactory
的getInvoker
方法
1 | public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) { |
可以看到这个方法返回的是一个AbstractProxyInvoker
的实例,通过它代理传入的type
类。到这里就完成了具体服务到Invoker
的转化。
然后来看protocol.export(invoker)
,同样直接来看DubboProtocol
类的export
方法
1 | public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException { |
这里可以看到返回的exporter
其实就是对传入的invoker
对象进行了包装。这里有一步需要注意,那就是openServer(url)
,来看一下
1 | private void openServer(URL url) { |
这里需要通过createServer(url)
去创建一个服务
1 | private ExchangeServer createServer(URL url) { |
server
实际由Exchangers.bind(url, requestHandler)
产生,主要作用是绑定并监听端口,默认由Netty实现。这里调用比较深也不是本篇重点,就不再深入了。
总结
本篇主要讲解了Dubbo生产者服务初始化的流程,简单概括起来就是将通过服务生成代理对象Invoker,并将Invoker包装成Exporter对象对外暴露,同时监听指定端口等待消费者的调用。