我們先來看看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。