直连方式 源码分析
直连创建代理的前半部分如下
下面详细分析
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方法,该方法对 invoker 添加属性,或执行其他处理 ,目前只有一个实现 DeprecatedInvokerListener,它是废弃的接口。
Invok