精尽 Dubbo 源码分析 —— Wrapper扩展点 Dubbo AOP实现

概述

Dubbo中也支持Spring AOP类似功能,通过装饰者模式,使用包装类包装原始的扩展点实例。在扩展点实现前后插入其他逻辑,实现AOP功能。说这很绕口啊,那什么是包装类呢?举个例子你就知道了

class A{
    private A a;
    public A(A a){
        this.a = a;
    }

    public void do(){
        // 插入扩展逻辑
        a.do();
    }
}

这里的插入扩展逻辑,是不是就是实现了AOP功能呢?比如说Protocol类,有2个Wrapper,分别是ProtocolFilterWrapper和ProtocolListenerWrapper,我们可以在dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.Protocol看到:

filter=com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper
listener=com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper

我们在最开始的Dubbo SPI的例子中,我们打个断点就很明显了,得到的myProtocol对象其实是这样的:

在这里插入图片描述

如果你调用export方法的话,会先经历ProtocolFilterWrapper的export方法,再经历ProtocolListenerWrapper的export方法,这样就实现了Spring AOP的功能

源码解析

aop 的实现是通过createExtension方法 实现


private T createExtension(String name) {
    // 1.加载配置文件所有拓展类,得到配置名-拓展类的map,从map中获取到拓展类
    Class<?> clazz = getExtensionClasses().get(name);
    if (clazz == null) {
        throw findException(name);
    }
    try {
        T instance = (T) EXTENSION_INSTANCES.get(clazz);
        if (instance == null) {
            // 2.通过反射创建实例
            // EXTENSION_INSTANCES这个map是配置名-拓展类实例的map
            EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.newInstance());
            instance = (T) EXTENSION_INSTANCES.get(clazz);
        }
        // 3.注入依赖,即IOC
        injectExtension(instance);
        Set<Class<?>> wrapperClasses = cachedWrapperClasses;
        if (CollectionUtils.isNotEmpty(wrapperClasses)) {
            // 4.循环创建Wrapper实例
            for (Class<?> wrapperClass : wrapperClasses) {
                // 通过反射创建Wrapper实例
                // 向Wrapper实例注入依赖,最后赋值给instance
                // 自动包装实现类似aop功能
                instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
            }
        }
        return instance;
    } catch (Throwable t) {
        throw new IllegalStateException("Extension instance (name: " + name + ", class: " +
                type + ") couldn't be instantiated: " + t.getMessage(), t);
    }
}

注意:
在循环创建Wrapper实例 实现的就是Wrapper实例按照加载的顺序嵌套实例化,这样能实现以下的对象:
在这里插入图片描述
当调用protocol 里头的方法时候,会一层层嵌套调用 实现aop效果!

注入依赖

ioc 的实现是通过injectExtension方法 实现


                
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值