Dubbo扩展点分类与缓存

Dubbo在加载扩展点时为了提高性能,会将需要Class与实例进行缓存。

Class缓存:Dubbo SPI获取扩展类时,会先从缓存中获取,如果缓存中不存在,则加载配置文件配置文件,根据配置把Class缓存到内存中,并不会直接全部初始化。

实例缓存:与获取Class相同,每次获取实例的时候,先从缓存中获取,如果获取不到,则重新加载并缓存起来。

这也是Dubbo SPI相对Java SPI性能上有优势的原因,Dubbo SPI缓存的Class并不会全部实例化,而是按需进行实例化并缓存。

被缓存的Class和对象实例可以根据不同的特性分为不同的类别:

1、普通扩展类

最基础的,配置在SPI配置文件中的扩展类实现。

2、包装扩展类

Wrapper类是一种装饰者模式,在构造方法中传入一个具体扩展接口的实现,属于Dubbo的自动包装特性。在ExtensionLoader在加载扩展时,如果发现这个扩展类包含其它扩展点作为构造函数参数,则这个扩展类就会被认定为是Wrapper类。

例如:

public class ProtocolFilterWrapper implements Protocol {

    private final Protocol protocol;

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

    ......
}

ProtocolFilterWrapper类实现了Protocol扩展接口,构造函数中传入的Protocol扩展对象便是Wrapper的增强对象,这样便可以将通用逻辑进行封装,使扩展点可以专注于自己的业务实现。

3、自适应扩展类

一个扩展接口会有多种实现类,具体使用哪个实现类可以不写死在配置或代码中,在运行时,通过传入URL中的某些参数动态确定,这属于扩展点的自适应特性。

4、其它

如扩展类加载器、扩展名缓存等。

ExtensionLoader中的各种缓存:

    // 扩展类与对应的扩展类加载器缓存
    private static final ConcurrentMap<Class<?>, ExtensionLoader<?>> EXTENSION_LOADERS = new ConcurrentHashMap<>();

    // 扩展类与类初始化后的实例
    private static final ConcurrentMap<Class<?>, Object> EXTENSION_INSTANCES = new ConcurrentHashMap<>();

    // ==============================

    private final Class<?> type;

    private final ExtensionFactory objectFactory;

    // 扩展类与扩展名缓存
    private final ConcurrentMap<Class<?>, String> cachedNames = new ConcurrentHashMap<>();

    // 普通扩展类缓存,不包括自适应扩展类和Wrapper类
    private final Holder<Map<String, Class<?>>> cachedClasses = new Holder<>();

    // 自动激活扩展类缓存
    private final Map<String, Object> cachedActivates = new ConcurrentHashMap<>();
    // 扩展名与扩展对象缓存
    private final ConcurrentMap<String, Holder<Object>> cachedInstances = new ConcurrentHashMap<>();
    // 实例化后的自适应(Adaptive)扩展对象,只能存在一个
    private final Holder<Object> cachedAdaptiveInstance = new Holder<>();
    // 自适应扩展类缓存
    private volatile Class<?> cachedAdaptiveClass = null;
    // 默认扩展名缓存
    private String cachedDefaultName;
    private volatile Throwable createAdaptiveInstanceError;

    // wrapper类缓存
    private Set<Class<?>> cachedWrapperClasses;
发布了149 篇原创文章 · 获赞 100 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/u011212394/article/details/102759173
今日推荐