ExtensionLoader概述
- 你无需先知道 扩展点,SPI,自适应 概念
- ExtensionLoader中最核心功能是创建对象,几乎所有的dubbo框架接口实现类对象都在该类中创建
- 对象在增删改查,为提升效率、有缓存参与;单个接口多个实现类、根据参数加载具体实现类,或加载对应接口多个实现类
ExtensionLoader属性
-
ExtensionLoader核心功能就是对以下属性的增删改查,弄清楚每个属性作用,则对ExtensionLoader就门清了
-
EXTENSION_LOADERS,EXTENSION_INSTANCES 作为常量存储,放到任何常量类中都可以
-
每个接口Class会创建对应的ExtensionLoader对象,并存储到 EXTENSION_LOADERS 中
-
每个接口的多个实现类Class创建的对应实例,存储到EXTENSION_INSTANCES;so 在java进程中通常对应接口实现类对象是单例的
-
其他属性需要在对应应用场景中解释
-
从属性命名中可将【extension:扩展】理解为对象实例
-
ExtensionFactory【对象工厂】 起到什么作用?
public class ExtensionLoader<T> {
// 常量存储 {class-ExtensionLoader} pair对
private static final ConcurrentMap<Class<?>, ExtensionLoader<?>> EXTENSION_LOADERS = new ConcurrentHashMap<>(64);
// 常量存储 {实现类class对象 ~ 实现类实例} pair对
private static final ConcurrentMap<Class<?>, Object> EXTENSION_INSTANCES = new ConcurrentHashMap<>(64);
// 接口class
private final Class<?> type;
// 对象工厂,不同接口对应 ExtensionLoader 的对象工厂属性是相同的
private final ExtensionFactory objectFactory;
/****以下属性是对象实例不同维度的缓存 需要在具体使用场景中理解*****/
private final ConcurrentMap<Class<?>, String> cachedNames = new ConcurrentHashMap<>();
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<>();
private final Holder<Object> cachedAdaptiveInstance = new Holder<>();
private volatile Class<?> cachedAdaptiveClass = null;
private String cachedDefaultName;
private volatile Throwable createAdaptiveInstanceError;
private Set<Class<?>> cachedWrapperClasses;
private Map<String, IllegalStateException> exceptions = new ConcurrentHashMap<>();
// 接口对应实现类名称存储路径
private static volatile LoadingStrategy[] strategies = loadLoadingStrategies();
...
}
ExtensionFactory 与 ExtensionLoader的关系
-
每个接口Class会创建对应的ExtensionLoader对象
-
每个ExtensionLoader<?>对象持有的ExtensionFactory属性是AdaptiveExtensionFactory;除去ExtensionLoader<ExtensionFactory>
-
ExtensionLoader<ExtensionFactory> 持有的ExtensionFactory属性是null
-
AdaptiveExtensionFactory类对象在整个应用运行中只有一个,为啥不采用静态属性?个人思考是因为 ExtensionLoader<ExtensionFactory> 对象 不需要ExtensionFactory属性
public class ExtensionLoader<T> {
private ExtensionLoader(Class<?> type) {
this.type = type;
// 创建objectFactory的【Adaptive:自适应】实例 或 不创建
// 先不用管自适应是什么含义
objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
}
private static <T> boolean withExtensionAnnotation(Class<T> type) {
return type.isAnnotationPresent(SPI.class);
}
// 通过接口Class get 对应ExtensionLoader<?> 对象
// ExtensionLoader 中最常用的方法;通常第一步先获取到接口class对应的ExtensionLoader对象
@SuppressWarnings("unchecked")
public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
if (type == null) {
throw new IllegalArgumentException("Extension type == null");
}
if (!type.isInterface()) {
throw new IllegalArgumentException("Extension type (" + type + ") is not an interface!");
}
// 接口必须有@SPI注解, dubbo框架的规定
// 如需要通过dubbo SPI 方式加载实现类需要遵守该规定
// SPI 方式加载,下文有解释
if (!withExtensionAnnotation(type)) {
throw new IllegalArgumentException("Extension type (" + type +
") is not an extension, because it is NOT annotated with @" + SPI.class.getSimpleName() + "!");
}
// 从存储常量map中获取
ExtensionLoader<T> loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
if (loader == null) {
EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type));
loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
}
return loader;
}
}
ExtensionFactory 功能
-
对象工厂全局只有一个ExtensionFactory的 AdaptiveExtensionFactory实例
-
通过SPI方式加载SpiExtensionFactory,SpringExtensionFactory实例,并存储到factories 列表中
-
SpiExtensionFactory 中getExtension 会从对应ExtensionLoader<?>中获取adaptive 对象实例
-
SpringExtensionFactory 中getExtension 会从ApplicationContext中获取bean 对象实例
-
AdaptiveExtensionFactory 中getExtension 会 for循环factories 调用getExtension 获取bean对象
-
项目中有可能会存在多个 bean工厂 如:dubbo框架 的SPI bean工厂,Spring框架 bean 工厂, Guice框架 bean工厂,自定义 bean工厂
-
AdaptiveExtensionFactory 构造器中会初始化所有bean工厂到factories列表中
-
通过AdaptiveExtensionFactory 工厂可以获取到任何bean工厂中对应的bean对象
-
此时的【adaptive:自适应】可理解为加载对应接口所有实现类,getExtension方法会遍历调用对应实现类的getExtension方法
-
什么是SPI加载方式,自适应还有哪些解释?
// 该类有@Adaptive
// 对应ExtensionLoader<ExtensionFactory> 中
// cachedAdaptiveInstance,cachedAdaptiveClass,createAdaptiveInstanceError
// 属性都与AdaptiveExtensionFactory相关
@Adaptive
public class AdaptiveExtensionFactory implements ExtensionFactory {
// 所有ExtensionFactory实现类实例对象【排查AdaptiveExtensionFactory】
// ExtensionLoader<ExtensionFactory>实例中cachedAdaptiveInstance属性是 AdaptiveExtensionFactory对象实例
private final List<ExtensionFac