目標:介紹dubbo-rpc-api中的各類listener監聽器的實現邏輯,內容略少,隨便撇兩眼,不是重點。
本文介紹監聽器的相關邏輯。在服務引用和服務發現中監聽器處於的位置請看下面的圖:java
這兩個監聽器所作的工做不是不少,來看看源碼理解一下。git
該類實現了Invoker,是服務引用監聽器的包裝類。github
/** * invoker對象 */ private final Invoker<T> invoker; /** * 監聽器集合 */ private final List<InvokerListener> listeners;
用到了裝飾模式,其中不少實現方法直接調用了invoker的方法。api
public ListenerInvokerWrapper(Invoker<T> invoker, List<InvokerListener> listeners) { // 若是invoker爲空則拋出異常 if (invoker == null) { throw new IllegalArgumentException("invoker == null"); } this.invoker = invoker; this.listeners = listeners; if (listeners != null && !listeners.isEmpty()) { // 遍歷監聽器 for (InvokerListener listener : listeners) { if (listener != null) { try { // 調用在服務引用的時候進行監聽 listener.referred(invoker); } catch (Throwable t) { logger.error(t.getMessage(), t); } } } } }
構造方法中直接調用了監聽器的服務引用。app
@Override public void destroy() { try { // 銷燬invoker invoker.destroy(); } finally { // 銷燬全部監聽的實體域 if (listeners != null && !listeners.isEmpty()) { for (InvokerListener listener : listeners) { if (listener != null) { try { listener.destroyed(invoker); } catch (Throwable t) { logger.error(t.getMessage(), t); } } } } } }
該方法是把服務引用的監聽器銷燬。ide
public abstract class InvokerListenerAdapter implements InvokerListener { /** * 引用服務 * @param invoker * @throws RpcException */ @Override public void referred(Invoker<?> invoker) throws RpcException { } /** * 銷燬 * @param invoker */ @Override public void destroyed(Invoker<?> invoker) { } }
該類是服務引用監聽器的適配類,沒有作實際的操做。源碼分析
@Activate(Constants.DEPRECATED_KEY) public class DeprecatedInvokerListener extends InvokerListenerAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(DeprecatedInvokerListener.class); @Override public void referred(Invoker<?> invoker) throws RpcException { // 當該引用的服務被廢棄時,打印錯誤日誌 if (invoker.getUrl().getParameter(Constants.DEPRECATED_KEY, false)) { LOGGER.error("The service " + invoker.getInterface().getName() + " is DEPRECATED! Declare from " + invoker.getUrl()); } } }
該類是當調用廢棄的服務時候打印錯誤日誌。this
該類是服務暴露監聽器包裝類。spa
/** * 服務暴露者 */ private final Exporter<T> exporter; /** * 服務暴露監聽者集合 */ private final List<ExporterListener> listeners;
用到了裝飾模式,其中不少實現方法直接調用了exporter的方法。日誌
public ListenerExporterWrapper(Exporter<T> exporter, List<ExporterListener> listeners) { if (exporter == null) { throw new IllegalArgumentException("exporter == null"); } this.exporter = exporter; this.listeners = listeners; if (listeners != null && !listeners.isEmpty()) { RuntimeException exception = null; // 遍歷服務暴露監聽集合 for (ExporterListener listener : listeners) { if (listener != null) { try { // 暴露服務監聽 listener.exported(this); } catch (RuntimeException t) { logger.error(t.getMessage(), t); exception = t; } } } if (exception != null) { throw exception; } } }
該方法中對於每一個服務暴露進行監聽。
@Override public void unexport() { try { // 取消暴露 exporter.unexport(); } finally { if (listeners != null && !listeners.isEmpty()) { RuntimeException exception = null; // 遍歷監聽集合 for (ExporterListener listener : listeners) { if (listener != null) { try { // 監聽取消暴露 listener.unexported(this); } catch (RuntimeException t) { logger.error(t.getMessage(), t); exception = t; } } } if (exception != null) { throw exception; } } } }
該方法是對每一個取消服務暴露的監聽。
public abstract class ExporterListenerAdapter implements ExporterListener { /** * 暴露服務 * @param exporter * @throws RpcException */ @Override public void exported(Exporter<?> exporter) throws RpcException { } /** * 取消暴露服務 * @param exporter * @throws RpcException */ @Override public void unexported(Exporter<?> exporter) throws RpcException { } }
該類是服務暴露監聽器的適配類,沒有作實際的操做。
該部分相關的源碼解析地址: https://github.com/CrazyHZM/i...
該文章講解了在服務引用和服務暴露中的各類listener監聽器,其中內容不多。接下來我將開始對rpc模塊的協議protocol進行講解。