栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

基于dubbo中Listener的实现方法

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

基于dubbo中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  Exporter export(Invoker invoker) throws RpcException {
    if (Constants.REGISTRY_PROTOCOL.equals(invoker.getUrl().getProtocol())) {
      return protocol.export(invoker);
    }
    return new ListenerExporterWrapper(protocol.export(invoker),
 Collections.unmodifiableList(ExtensionLoader.getExtensionLoader(ExporterListener.class)
     .getActivateExtension(invoker.getUrl(), Constants.EXPORTER_LISTENER_KEY)));
  }

  public  Invoker refer(Class type, URL url) throws RpcException {
    if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
      return protocol.refer(type, url);
    }
    return new ListenerInvokerWrapper(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> wrappers = cachedWrapperClasses;
  if (wrappers == null) {
    cachedWrapperClasses = new ConcurrentHashSet>();
    wrappers = cachedWrapperClasses;
  }
  wrappers.add(clazz);
} catch (NoSuchMethodException e) {

上面也可以看到用一场作为一个判断逻辑。

ExtensionLoader中getExtension(String name)方法中会调用createExtension(String name)这个方法中将cachedWrapperClasses利用了起来,具体实现就是将被装饰类实例作为参数调用warpper类的自身复制构造函数,这样就会把被装饰累包装起来,从而达到,当有调用被装饰类的方法是就可以执行到warpper中的逻辑代码了,实现都是调用了clazz.getConstructor方法,代码片段:

Set> 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,如此自己的业务代码中就不需要出现一个空方法了。

以上这篇基于dubbo中Listener的实现方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/144896.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号