10. Dubbo原理解析-Listener & filter
Listener
ExporterListener:
dubbo在服務暴露(exporter)以及銷燬暴露(unexporter)服務的過程中提供了回撥視窗,供使用者做業務處理。ProtocolListenerWrapper在暴露過程中構建了監聽器鏈
public class ProtocolListenerWrapper implements Protocol {
public <T> Exporter<T> export(Invoker<T>invoker)throws RpcException {
……. //註冊中心程式碼
return
}
}
1. 根據Dubbo的SPI擴充套件機制獲取所有實現了ExporterListener的監聽器listeners
2. Protocol.export(invoker)暴露服務返回結果exporter物件
3. ListenerExporterWrapper裝飾exporter, 在構造器中遍歷listeners構建export的監聽鏈
4. ListenerExporterWrapper實現Exproter<T>介面,在unexport方法實現中構建unexport的監聽鏈
InvokerListener:
dubbo在服務引用(refer)以及銷燬引用(destroy)服務的過程中提供了回撥視窗,供使用者做業務處理。ProtocolListenerWrapper在暴露過程中構建了監聽器鏈
public <T> Invoker<T> refer(Class<T> type,URL url)throws RpcException {
returnnew ListenerInvokerWrapper<T>(protocol.refer(type, url), Collections.unmodifiableList(ExtensionLoader.getExtensionLoader(InvokerListener.class).getActivateExtension(url,Constants.INVOKER_LISTENER_KEY)));
}
1. 根據Dubbo的SPI擴充套件機制獲取所有實現了InvokerListener的監聽器listeners
2. Protocol.refer(type, url)暴露服務返回結果invoker物件
3. ListenerInvokerWrapper裝飾invoker, 在構造器中遍歷listeners構建referer的監聽鏈3. ListenerInvokerWrapper裝飾invoker, 在構造器中遍歷listeners構建referer的監聽鏈
4. ListenerInvokerWrapper實現Invoker<T>介面,在destory方法實現中構建destory的監聽鏈
Dubbo的開源版本中沒有監聽的實現,但是開放了口子,業務方如有需要可以利用這個功能實現特定的業務
Filter
Filter:是一種遞迴的鏈式呼叫,用來在遠端呼叫真正執行的前後加入一些邏輯,跟aop的攔截器servlet中filter概念一樣的
Filter介面定義
@SPI
public interface Filter {
Result invoke(Invoker<?> invoker,Invocation invocation) throws RpcException;
}
ProtocolFilterWrapper:在服務的暴露與引用的過程中根據KEY是PROVIDER還是CONSUMER來構建服務提供者與消費者的呼叫過濾器鏈
public <T> Exporter<T> export(Invoker<T>invoker)throws RpcException {
return protocol.export(buildInvokerChain(invoker, Constants.SERVICE_FILTER_KEY, Constants.PROVIDER));
}
public <T> Invoker<T> refer(Class<T> type,URL url)throws RpcException {
return buildInvokerChain(protocol.refer(type, url),Constants.REFERENCE_FILTER_KEY, Constants.CONSUMER);
}
Filter的實現類需要打上@Activate註解, @Activate的group屬性是個string陣列,我們可以通過這個屬性來指定這個filter是在consumer, provider還是兩者情況下啟用,所謂啟用就是能夠被獲取,組成filter鏈
List<Filter> filters =ExtensionLoader.getExtensionLoader(Filter.class).getAct ivateExtension(invoker.getUrl(),key, group);
Key就是SERVICE_FILTER_KEY還是REFERENCE_FILTER_KEY
Group就是consumer或者provider
構建filter鏈,當我們獲取啟用的filter集合後就通過buildInvokerChain方法來構建
for (int i = filters.size() - 1; i >= 0; i --) {
final Filter filter = filters.get(i);
final Invoker<T> next = last;
last = new Invoker<T>() {
public Result invoke(Invocation invocation)throws RpcException {
return filter.invoke(next, invocation);
}
。。。。。。。 //其他方法
};
}
以上程式碼展示了構建filter鏈的過程
Dubbo內容提供了大量內部實現,用來實現呼叫過程額外功能, 如向監控中心傳送呼叫資料, Tps限流等等, 每個filer專注一塊功能。使用者同樣可以通過Dubbo的SPI擴充套件機制現在自己的功能