dubbo源码分析2-consumer代理创建和连接分析2

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

直连方式 源码分析

直连创建代理的前半部分如下

下面详细分析

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方法,

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值