dubbo 服务暴露过程的序列图如下[图片在新的窗口查看更清晰]
本文由javacoder.cn整理, 谢绝转载,谢谢
1)熟悉spring 上下文启动的同学都知道,spring会先解析xml生成BeanDefination, DubboBeanDefinitionParser的parse方法中完成dubbo 命名空间的解析。
2)在applicationContext 启动的refresh阶段会广播ApplicationEvent事件, 触发ApplicationListener.onApplicationEvent() 方法的执行, ServiceBean实现了ApplicationListener接口,所以onApplicationEvent()方法开始执行。
3)ProxyFactory$Adpative是dubbo通过Javassist字节码库动态产生的一个类, 主要功能利用dubbo的接口扩展机制适配指定的实现, 实现的代码如下[设置log4j.logger.com.alibaba.dubbo=debug 的输出,没有格式化,哈原始格式]
package com.alibaba.dubbo.rpc; import com.alibaba.dubbo.common.extension.ExtensionLoader; public class ProxyFactory$Adpative implements com.alibaba.dubbo.rpc.ProxyFactory { public com.alibaba.dubbo.rpc.Invoker getInvoker(java.lang.Object arg0, java.lang.Class arg1, com.alibaba.dubbo.common.URL arg2) throws java.lang.Object { if (arg2 == null) throw new IllegalArgumentException("url == null"); com.alibaba.dubbo.common.URL url = arg2; String extName = url.getParameter("proxy", "javassist"); if(extName == null) throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.ProxyFactory) name from url(" + url.toString() + ") use keys([proxy])"); com.alibaba.dubbo.rpc.ProxyFactory extension = (com.alibaba.dubbo.rpc.ProxyFactory)ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.ProxyFactory.class).getExtension(extName); return extension.getInvoker(arg0, arg1, arg2); } public java.lang.Object getProxy(com.alibaba.dubbo.rpc.Invoker arg0) throws com.alibaba.dubbo.rpc.Invoker { if (arg0 == null) throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument == null"); if (arg0.getUrl() == null) throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument getUrl() == null"); com.alibaba.dubbo.common.URL url = arg0.getUrl(); String extName = url.getParameter("proxy", "javassist"); if(extName == null) throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.ProxyFactory) name from url(" + url.toString() + ") use keys([proxy])"); com.alibaba.dubbo.rpc.ProxyFactory extension = com.alibaba.dubbo.rpc.ProxyFactory)ExtensionLoader .getExtensionLoader(com.alibaba.dubbo.rpc.ProxyFactory.class).getExtension(extName); return extension.getProxy(arg0); } }
ProxyFactory$Adpative的getInvoker()方法根据proxy 参数, 调用ExtensionLoader.getExtensionLoader()获取对应实现的ProxyFactory类,然后调用改实现的getInvoker()方法。
ProxyFactory$Adpative的getInvoker()方法类似。
4)JavassistProxyFactory.getInvoker() 实现就是反射调用指定的方法。封装成了Wrapper类
5)Protocol$Adpative 的原理同ProxyFactory$Adpative, 不再累述
6)RegistryProtocol.export 使用同样的原理,通过Protocol$Adpative 适配器,将真正的export工作代理给了DubboProtocol
7)DubboProtocol.export
核心代码参考openServer 方法, 创建dubbo 服务的监听socket 等
8)ProtocolFilterWrapper.export 将filter 加入到Invoker中
最核心的代码在buildInvokerChain方法中,为每个filter 产生一个Invoker,然后绑定到Invoker 链中。
private static <T> Invoker<T> buildInvokerChain(final Invoker<T> invoker, String key, String group) { Invoker<T> last = invoker; List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class) .getActivateExtension(invoker.getUrl(), key, group); for (int i = filters.size() - 1; i >= 0; i --) { final Filter filter = filters.get(i); final Invoker<T> next = last; last = new Invoker<T>() { //删了其他非核心的代码 public Result invoke(Invocation invocation) throws RpcException { return filter.invoke(next, invocation); } }; } return last; }
9)RegistryProtocol.getRegistry 获取注册中心的实现,根据<dubbo:registry/>元素配置获取对应的RegistryFactory实现,获取Registry对象。
10)ZookeeperRegistry.register调用具体的注册中心完成服务的注册。至此服务暴露完成
Posted in: MySQL practise
Comments are closed.