我们先来看看Router的继承体系图
从图中可以看出,他有三个实现类,分别是ConditionRouter,MockInvokersSelector,ScriptRouter
MockInvokersSelector
判断是否需要筛选mock invoker的路由,相对比较简单
@Override
public <T> List<Invoker<T>> route(final List<Invoker<T>> invokers,
URL url, final Invocation invocation) throws RpcException {
if (invocation.getAttachments() == null) {
// 没有配置参数,直接选择正常的invoker
return getNormalInvokers(invokers);
} else {
// 获取mock配置参数,判断是否需要mock
String value = invocation.getAttachments().get(Constants.INVOCATION_NEED_MOCK);
if (value == null)
// 选择正常invoker
return getNormalInvokers(invokers);
else if (Boolean.TRUE.toString().equalsIgnoreCase(value)) {
// 选择mock invoker
return getMockedInvokers(invokers);
}
}
return invokers;
}
private <T> List<Invoker<T>> getMockedInvokers(final List<Invoker<T>> invokers) {
if (!hasMockProviders(invokers)) {
return null;
}
List<Invoker<T>> sInvokers = new ArrayList<Invoker<T>>(1);
for (Invoker<T> invoker : invokers) {
if (invoker.getUrl().getProtocol().equals(Constants.MOCK_PROTOCOL)) {
sInvokers.add(invoker);
}
}
return sInvokers;
}
private <T> List<Invoker<T>> getNormalInvokers(final List<Invoker<T>> invokers) {
if (!hasMockProviders(invokers)) {
return invokers;
} else {
// 剔除mock的invoker
List<Invoker<T>> sInvokers = new ArrayList<Invoker<T>>(invokers.size());
for (Invoker<T> invoker : invokers) {
if (!invoker.getUrl().getProtocol().equals(Constants.MOCK_PROTOCOL)) {
sInvokers.add(invoker);
}
}
return sInvokers;
}
}
private <T> boolean hasMockProviders(final List<Invoker<T>> invokers) {
boolean hasMockProvider = false;
for (Invoker<T> invoker : invokers) {
// 判断是否mock invoker的方式:判断protocol是否mock协议
if (invoker.getUrl().getProtocol().equals(Constants.MOCK_PROTOCOL)) {
hasMockProvider = true;
break;
}
}
return hasMockProvider;
}
ScriptRouter
脚本路由规则 支持 JDK 脚本引擎的所有脚本,比如:javascript, jruby, groovy 等,通过 type=javascript 参数设置脚本类型,缺省为 javascript。