直连方式 源码分析
直连创建代理的前半部分如下

下面详细分析
ProtocolFilterWrapper.refer(Class<T>, URL)
创建包含 Filter的invoker执行链。
public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {//注册中心方式
return protocol.refer(type, url);
}
//创建包含Filter的 Invoker执行链
return buildInvokerChain(protocol.refer(type, url), Constants.REFERENCE_FILTER_KEY, Constants.CONSUMER);//直连方式
}
//创建包含Filter的 Invoker执行链,此时所有的Filter和invoker未组成调用链,需要从尾到头挂一遍。相当于编程式构建AOP功能
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);
if (filters.size() > 0) {
for (int i = filters.size() - 1; i >= 0; i--) {
final Filter filter = filters.get(i);
// 从尾部开始,每次获取最后一个invoker , 结合 filter.invoke(next, invocation)中 都是执行 next.invoke()的逻辑,构建过滤器链。
// 假设filters中的元素索引 是 0~n , 0处的元素是过滤器链的最外层,n 位于last前。
final Invoker<T> next = last;
last = new Invoker<T>() {
public Class<T> getInterface() {
return invoker.getInterface();
}
public URL getUrl() {
return invoker.getUrl();
}
public boolean isAvailable() {
return invoker.isAvailable();
}
public Result invoke(Invocation invocation) throws RpcException {
return filter.invoke(next, invocation);
}
public void destroy() {
invoker.destroy();
}
@Override
public String toString() {
return invoker.toString();
}
};
}
}
return last;
}
QosProtocolWrapper.refer(Class<T>, URL)
此时 QosProtocolWrapper 嵌套如下图

public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {//注册中心方式
startQosServer(url);//如果是注册协议,启动 QosServer
return protocol.refer(type, url);
}
return protocol.refer(type, url);//直连方式
}
QosServer服务于telnet访问和 http访问。
ProtocolListenerWrapper.refer(Class<T>, URL)
public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {//注册中心方式
return protocol.refer(type, url);
}
return new ListenerInvokerWrapper<T>(protocol.refer(type, url),
Collections.unmodifiableList(
ExtensionLoader.getExtensionLoader(InvokerListener.class)
.getActivateExtension(url, Constants.INVOKER_LISTENER_KEY)));
}
方法逻辑:如果是注册协议,直接执行协议引用,否则需要包装。
ListenerInvokerWrapper 构造方法分析
public ListenerInvokerWrapper(Invoker<T> invoker, List<InvokerListener> listeners) {
if (invoker == null) {
throw new IllegalArgumentException("invoker == null");
}
this.invoker = invoker;
this.listeners = listeners;
if (listeners != null && listeners.size() > 0) {
for (InvokerListener listener : listeners) {
if (listener != null) {
try {
listener.referred(invoker);
} catch (Throwable t) {
logger.error(t.getMessage(), t);
}
}
}
}
}
new ListenerInvokerWrapper 保存了Invoker<T> invoker和List<InvokerListener> listeners,循环执行了listener的referred方法,

这篇博客深入分析了Dubbo消费者在直连模式下如何创建代理和建立连接。首先,`ProtocolFilterWrapper`构建了包含过滤器的`Invoker`执行链,接着`QosProtocolWrapper`支持telnet和http服务,而`ProtocolListenerWrapper`获取并执行自定义的监听器。在协议层,`DubboProtocol`创建`DubboInvoker`,管理`ExchangeClient`,并添加心跳属性。交换层通过`HeaderExchangeClient`进行连接,创建`HeaderExchangeChannel`并启动心跳线程。最后,传输层由`Transporters`实现,通过`NettyTransporter`创建Netty客户端,完成连接过程。
最低0.47元/天 解锁文章
548

被折叠的 条评论
为什么被折叠?



