中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Listener如何在dubbo中實現

發布時間:2020-12-01 17:18:36 來源:億速云 閱讀:152 作者:Leah 欄目:編程語言

本篇文章給大家分享的是有關Listener如何在dubbo中實現,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

拿ProtocolListenerWrapper為例子,看源碼的時候發現它是一個裝飾類的標準實現有一個自身的復制構造函數,把被包裝者復制進來,然后結合裝飾部分的操作。看下ProtocolListenerWrapper類有這樣的代碼:

public class ProtocolListenerWrapper implements Protocol {

  private final Protocol protocol;

  public ProtocolListenerWrapper(Protocol protocol){
    if (protocol == null) {
      throw new IllegalArgumentException("protocol == null");
    }
    this.protocol = protocol;
  }

  public int getDefaultPort() {
    return protocol.getDefaultPort();
  }

  public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
    if (Constants.REGISTRY_PROTOCOL.equals(invoker.getUrl().getProtocol())) {
      return protocol.export(invoker);
    }
    return new ListenerExporterWrapper<T>(protocol.export(invoker),
        Collections.unmodifiableList(ExtensionLoader.getExtensionLoader(ExporterListener.class)
            .getActivateExtension(invoker.getUrl(), Constants.EXPORTER_LISTENER_KEY)));
  }

  public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
    if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
      return protocol.refer(type, url);
    }
    return new ListenerInvokerWrapper<T>(protocol.refer(type, url),
        Collections.unmodifiableList(
            ExtensionLoader.getExtensionLoader(InvokerListener.class)
            .getActivateExtension(url, Constants.INVOKER_LISTENER_KEY)));
  }

  public void destroy() {
    protocol.destroy();
  }

}

而我們在ExtensionLoader里找到了這份代碼片段clazz.getConstructor()方法就是去匹配前面提到的裝飾模式用到的方式。

而這些類作為插件會被放入cachedWrapperClasses進行緩存。而對這個緩存的使用就是解開listenter調用實現的鑰匙。

try {
  clazz.getConstructor(type);
  Set<Class<?>> wrappers = cachedWrapperClasses;
  if (wrappers == null) {
    cachedWrapperClasses = new ConcurrentHashSet<Class<?>>();
    wrappers = cachedWrapperClasses;
  }
  wrappers.add(clazz);
} catch (NoSuchMethodException e) {

上面也可以看到用一場作為一個判斷邏輯。

ExtensionLoader中getExtension(String name)方法中會調用createExtension(String name)這個方法中將cachedWrapperClasses利用了起來,具體實現就是將被裝飾類實例作為參數調用warpper類的自身復制構造函數,這樣就會把被裝飾累包裝起來,從而達到,當有調用被裝飾類的方法是就可以執行到warpper中的邏輯代碼了,實現都是調用了clazz.getConstructor方法,代碼片段:

Set<Class<?>> wrapperClasses = cachedWrapperClasses;
if (wrapperClasses != null && wrapperClasses.size() > 0) {
  for (Class<?> wrapperClass : wrapperClasses) {
    instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
  }
}

再回去看一下ProtocolListenerWrapper,我們可以發現繼承Protocol中的export方法是對外開放service的入口方法,它返回exporter,代碼中實際是返回了ListenerExporterWrapper,這也是個裝飾類,不過沒有使用上面提到的機制,只是把exporter和listener進行類包裝,在構造函數里將listener執行。至此我們終于找到了執行listener的代碼。

在dubbo的開發中listener是及其重要的一個擴展口子,在服務對外時執行一些自己想做的事情就些各類繼承ExporterListener

在引用服務的時候想做些自己的事就寫個類繼承InvokerListener。

另外,ExporterListener為例,發現他的子類中有一個ExporterListenerAdapter,兩個空方法,代碼:

public abstract class ExporterListenerAdapter implements ExporterListener {

  public void exported(Exporter<?> exporter) throws RpcException {
  }

  public void unexported(Exporter<?> exporter) throws RpcException {
  }

}

這是個技巧吧,剛剛上面提到自己要寫擴展類的時候就不直接繼承ExporterListener了,因為直接繼承接口會強制要求實現兩個方法的,而實際編碼中dubbo的作者應該也發現這兩個方法是完全不同的業務時使用,所有我們可以只繼承ExporterListenerAdapter,如此自己的業務代碼中就不需要出現一個空方法了。

以上就是Listener如何在dubbo中實現,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

西宁市| 合山市| 德阳市| 波密县| 拜城县| 佛冈县| 石城县| 本溪市| 武威市| 当涂县| 岐山县| 梨树县| 来凤县| 巴青县| 涿鹿县| 卢氏县| 衡山县| 双柏县| 华蓥市| 聂荣县| 天柱县| 九龙坡区| 青铜峡市| 敦化市| 涟源市| 太康县| 扎鲁特旗| 杭锦旗| 文化| 巴南区| 揭阳市| 二连浩特市| 改则县| 商河县| 鹤岗市| 思南县| 专栏| 民权县| 台北县| 红安县| 横山县|