对于接口方法,我们可以按照需求标注 Adaptive 注解。
在获取实现类的过程中,如果某个实现类被 Adaptive 注解修饰了,那么该类就会被赋值给 cachedAdaptiveClass 变量。
以 Protocol 接口为例,该接口的 destroy 和 getDefaultPort 未标注 Adaptive 注解,其他方法均标注了 Adaptive 注解。
Dubbo 不会为没有标注 Adaptive 注解的方法生成代理逻辑,对于该种类型的方法,仅会生成一句抛出异常的代码。
RegistryService的Registry ->AbstractRegistry的subscribe方法
FailbackRegistry的构造方法调用父类的构造方法,加载本地文件,同时调用自己的retry方法 zookeeperRegistry的doSubscribe方法调用父类FailbackRegistry的notify方法,执行super.notify(),执行父类 abstractRegistry中的notify.
将变化的url保存在缓存中,保存进properties,通过properties保存进file文件
调用RegistryDirectory 中的notify方法,执行refreshInvokers刷新本地缓存的服务者地址()
调用listener的notify方法 执行子类的RegistryDirectory的notify方法->执行refreshInvoker方法,刷新服务者本地缓存,并删除不可用的服务者信息
本地调用 则生成injvmInvoker 代理
远程调用
1.如果配置了服务者地址,则表示直连,则将地址放进map
2.则加载注册额中心地址,并放进map
2.对上面的map里面的信息创建dubboInvoker(直连情况下)
2.如果注册中心链接不为空 非直连情况,则需要使用cluster将创建的所有invoker进行合并
创建proxy代理类
DubboProtocol 创建inviker时候
public <T> Invoker<T> refer(Class<T> serviceType, URL url) throws RpcException {
optimizeSerialization(url);
// 创建 DubboInvoker
DubboInvoker<T> invoker = new DubboInvoker<T>(serviceType, url, getClients(url), invokers);
invokers.add(invoker);
return invoker;
}
调用了getClients生成ExchangeClient客户端
RegistryProtocol中的doRefer方法具体进行注册zk(订阅 providers、configurators、routers 等节点数据),同时获取服务者子节点信息,放进urls中 进行处理
//服务调用过程
InvokerInvocationHandler invoke方法 拦截object中的方法
-->MockClusterInvoker invoke方法 是否配置force,判断是否执行mock逻辑,或者调用远程
—> AbstractClusterInvoker#invoke(Invocation) 数据校验,创建负载均衡实例
—> FailoverClusterInvoker#doInvoke(Invocation, List<Invoker<T>>, LoadBalance)
—> Filter#invoke(Invoker, Invocation) // 包含多个 Filter 调用
—> ListenerInvokerWrapper#invoke(Invocation)
-->AbstractInvoker invoke方法设置invocation的参数(path,attachment),
-->DubboInvoker doInvoke ExchangeClient客户端(在注册消费者时候创建的客户端)调用发送请求(异步无返回(返回空的RpcResult),异步又返回(暂时返回空的RpcResult),同步调用(get方法需等待DefaultFuture实现))
-->ReferenceCountExchangeClient request(Object request, int timeout) 调用send接口 由HeaderExchangeClient实现
-->HeaderExchangeClient request(Object request, int timeout) 返回ResponseFuture
-->HeaderExchangeChannel request(Object request, int timeout)创建Request对象
-->NettyClient send方法(父类AbstractPeer的实现)
--> AbstractClient send(Object message, boolean sent) 获取到channel
--> NettyChannel send(Object message, boolean sent) 发送消息
--> NioClientSocketChannel#write(Object) 写数据信息
//接收到调用请求处理过程
解码器将数据包解析成 Request 对象后 NettyHandler 的 messageReceived 方法紧接着会收到这个对象,并将这个对象继续向下传递
NettyHandler#messageReceived(ChannelHandlerContext, MessageEvent) 获取NettyChannel实例,
—> AbstractPeer#received(Channel, Object) 是否关闭校验
—> MultiMessageHandler#received(Channel channel, Object message) 按照message进行处理(MultiMessage类型的,则遍历调用,否则直接调用)
—> HeartbeatHandler#received(Channel, Object) 心跳递增,并设置Attribute,并创建Response
—> AllChannelHandler#received(Channel, Object) 将数据分发到线程池
—> ExecutorService#execute(Runnable) // 由线程池执行后续的调用逻辑
-->DecodeHandler received对接收到的数据进行解码
-->HeaderExchangeHandler received(Channel channel, Object message) 处理事件转换对象
-->DubboProtocol received接收到请求
-->DubboProtocol reply方法根据Invocation获取invoker实例,执行invoke方法,
-->AbstractProxyInvoker invoke(Invocation invocation) // 调用 doInvoke(子类JavassistProxyFactory实现) 执行后续的调用,并将调用结果封装到 RpcResult 中,
Wrapper 是一个抽象类,其中 invokeMethod 是一个抽象方法。Dubbo 会在运行时通过 Javassist 框架为 Wrapper 生成实现类,并实现 invokeMethod 方法,该方法最终会根据调用信息调用具体的服务
-->JavassistProxyFactory doInvoke(T proxy, String methodName,Class<?>[] parameterTypes,Object[] arguments)方法,调用具体的wrapper.invokeMethod()