基于dubbo中Listener的实现方法

网友投稿 337 2023-04-21


基于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(

Extenshttp://ionLoader.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 TvEZzw= 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 {

}

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:约定优于配置_动力节点Java学院整理
下一篇:设计模式之责任链模式_动力节点Java学院整理
相关文章

 发表评论

暂时没有评论,来抢沙发吧~