资讯专栏INFORMATION COLUMN

dubbo扩展点的AOP

lmxdawn / 2982人阅读

摘要:扩展点的对的扩展点做一些切面功能的扩展从的代码说起关键说明,是在里面加载的,是符合某种特征的扩展接口实现类的称呼。

dubbo扩展点的AOP

对dubbo的扩展点做一些切面功能的扩展

从ExtensionLoader的createExtension代码说起
    @SuppressWarnings("unchecked")
    private T createExtension(String name) {
        Class clazz = getExtensionClasses().get(name);
        if (clazz == null) {
            throw findException(name);
        }
        try {
            T instance = (T) EXTENSION_INSTANCES.get(clazz);
            if (instance == null) {
                EXTENSION_INSTANCES.putIfAbsent(clazz, (T) clazz.newInstance());
                instance = (T) EXTENSION_INSTANCES.get(clazz);
            }
            injectExtension(instance);
            
            
            Set> wrapperClasses = cachedWrapperClasses;
            //begin 
            if (wrapperClasses != null && wrapperClasses.size() > 0) {
                for (Class wrapperClass : wrapperClasses) {
                    instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
                }
            }
            //end 
            return instance;
        } catch (Throwable t) {
            throw new IllegalStateException("Extension instance(name: " + name + ", class: " +
                    type + ")  could not be instantiated: " + t.getMessage(), t);
        }
    }

关键说明,

cachedWrapperClasses是在loadFile里面加载的,"WrapperClass"是符合某种特征的扩展接口实现类的称呼。例如ProtocolFilterWrapper

和ProtocolListenerWrapper。他们共同特征就是带有Protocol接口的构造函数。

/**
 * ListenerProtocol
 *
 * @author william.liangf
 */
public class ProtocolFilterWrapper implements Protocol {

    private final Protocol protocol;

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

    private static  Invoker buildInvokerChain(final Invoker invoker, String key, String group) {
        Invoker last = invoker;
        List filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.getUrl(), key, group);
        if (filters.size() > 0) {
            for (int i = filters.size() - 1; i >= 0; i--) {
                final Filter filter = filters.get(i);
                final Invoker next = last;
                last = new Invoker() {

                    public Class getInterface() {
                        return invoker.getInterface();
                    }

                    public URL getUrl() {
                        return invoker.getUrl();
                    }

                    public boolean isAvailable() {
                        return invoker.isAvailable();
                    }

                    public Result invoke(Invocation invocation) throws RpcException {
                        return filter.invoke(next, invocation);
                    }

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

                    @Override
                    public String toString() {
                        return invoker.toString();
                    }
                };
            }
        }
        return last;
    }

    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 protocol.export(buildInvokerChain(invoker, Constants.SERVICE_FILTER_KEY, Constants.PROVIDER));
    }

    public  Invoker refer(Class type, URL url) throws RpcException {
        if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
            return protocol.refer(type, url);
        }
        return buildInvokerChain(protocol.refer(type, url), Constants.REFERENCE_FILTER_KEY, Constants.CONSUMER);
    }

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

}

instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance)); 就是将拿到的instance放到一个包装类中,然后经过一层包装之后,在放到另外一个包装类中,

通过这种方式dubbo实现了扩展点的AOP

遇到的设计模式

装饰器模式

动态代理模式

多次使用装饰类,实现了dubbo扩展点的AOP功能

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69179.html

相关文章

  • 聊聊Dubbo - Dubbo扩展机制实战

    摘要:今天我想聊聊的另一个很棒的特性就是它的可扩展性。的扩展机制在的官网上,描述自己是一个高性能的框架。接下来的章节中我们会慢慢揭开扩展机制的神秘面纱。扩展扩展点的实现类。的定义在配置文件中可以看到文件中定义了个的扩展实现。 摘要: 在Dubbo的官网上,Dubbo描述自己是一个高性能的RPC框架。今天我想聊聊Dubbo的另一个很棒的特性, 就是它的可扩展性。 Dubbo的扩展机制 在Dub...

    techstay 评论0 收藏0
  • 聊聊Dubbo - Dubbo扩展机制源码解析

    摘要:什么是类那什么样类的才是扩展机制中的类呢类是一个有复制构造函数的类,也是典型的装饰者模式。代码如下有一个参数是的复制构造函数有一个构造函数,参数是扩展点,所以它是一个扩展机制中的类。 摘要: 在Dubbo可扩展机制实战中,我们了解了Dubbo扩展机制的一些概念,初探了Dubbo中LoadBalance的实现,并自己实现了一个LoadBalance。是不是觉得Dubbo的扩展机制很不错呀...

    lmxdawn 评论0 收藏0
  • dubbo扩展点机制

    摘要:在中配置,以配置为例整个,最先使用的地方从里面读取这个配置使用接口的中获取具体的实现类中有两个值当主线程被外部终止时,会触发,执行的与方法通知下面的锁操作,主线程正常走完代码,并最终停止。 spring是如何启动容器的 常见的一种在本地使用main方法启动spring的方法 public static void main(String[] args) throws Except...

    Rindia 评论0 收藏0
  • dubbo扩展点的IOC

    摘要:属性上篇文章中,提到在获取扩展点接口对应的的时候,会执行私有构造函数。因为此时是,即当为时,即我们可以看出,所有非扩展点接口都会执行对应的实例的方法返回一个实例,即对象。 spring是如何获得容器中管理的类的 拿到applicationContext,就可以调用getBean方法来获得Spring的bean对象了 public class SpringContextUtil impl...

    Zoom 评论0 收藏0
  • Dubbo SPI机制和IOC

    摘要:要构建自适应实例,先要有自适应的实现类,实现类有两种方式一种通过配置文件,一种是通过是字节码的方式动态生成。 SPI机制 SPI,即(service provider interface)机制,有很多组件的实现,如日志、数据库访问等都是采用这样的方式,一般通用组件为了提升可扩展性,基于接口编程,将操作接口形成标准规范,但是可以开放多种扩展实现,这种做法也符合开闭设计原则,使组件具有可插...

    Scorpion 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<