
在Cluster入口处,当走到step4时,就会涉及到Directory了。
先看下Directory的类图
step4时首先进入
//AbstractDirectory
public List<Invoker<T>> list(Invocation invocation) throws RpcException {
//抽象方法,子类实现
List<Invoker<T>> invokers = doList(invocation);//5 RegistryDirectory.doList-->6 7
// 根据路由规则,找出 Invoker 集合
List<Router> localRouters = this.routers; // local reference 本地引用,避免并发问题
if (localRouters != null && !localRouters.isEmpty()) {
for (Router router : localRouters) {
if (router.getUrl() == null || router.getUrl().getParameter(Constants.RUNTIME_KEY, false)) {
invokers = router.route(invokers, getConsumerUrl(), invocation);//6
}
}
}
return invokers;
}
//RegistryDirectory
public List<Invoker<T>> doList(Invocation invocation) {
List<Invoker<T>> invokers = null;
Map<String, List<Invoker<T>>> localMethodInvokerMap = this.methodInvokerMap; // local reference
if (localMethodInvokerMap != null && localMethodInvokerMap.size() > 0) {
String methodName = RpcUtils.getMethodName(invocation);
Object[] args = RpcUtils.getArguments(invocation);
if (args != null && args.length > 0 && args[0] != null
&& (args[0] instanceof String || args[0].getClass().isEnum())) {
//way1.根据第一个参数枚举路由。用不到。忽略
invokers = localMethodInvokerMap.get(methodName + args[0]);
}
if (invokers == null) {
//way2.根据方法名获得 Invoker 集合(基本到这里就会找到)
invokers = localMethodInvokerMap.get(methodName);
}
//way3.使用全量 Invoker 集合
if (invokers == null) {
invokers = localMethodInvokerMap.get("*");
}
if (invokers == null) {
//way4.使用 methodInvokerMap 第一个 Invoker 集合。防御性编程。
Iterator<List<Invoker<T>>> iterator = localMethodInvokerMap.values().iterator();
if (iterator.hasNext()) {
invokers = iterator.next();
}
}
}
return invokers == null ? new ArrayList<Invoker<T>>(0) : invokers;
}