ExtensionLoader
- getExtensionLoader 获取扩展点加载器 并加载所对应的所有的扩展点实现
- getExtension 根据name 获取扩展的指定实现
成员变量
private static final Logger logger = LoggerFactory.getLogger(ExtensionLoader.class);
private static final Pattern NAME_SEPARATOR = Pattern.compile("\\s*[,]+\\s*");
/**
* 一个扩展接口对应一个 ExtensionLoader 实例,
* 该集合缓存了全部 ExtensionLoader 实例,
* 其中的 Key 为扩展接口,Value 为加载其扩展实现的 ExtensionLoader 实例。
*/
private static final ConcurrentMap<Class<?>, ExtensionLoader<?>> EXTENSION_LOADERS = new ConcurrentHashMap<>(64);
/**
* 该集合缓存了扩展实现类与其实例对象的映射关系。在前文示例中,Key 为 Class,Value 为 DubboProtocol 对象。
*/
private static final ConcurrentMap<Class<?>, Object> EXTENSION_INSTANCES = new ConcurrentHashMap<>(64);
/**
前 ExtensionLoader 实例负责加载扩展接口。
*/
private final Class<?> type;
private final ExtensionFactory objectFactory;
/**
*
* 缓存了该 ExtensionLoader 加载的扩展实现类与扩展名之间的映射关系。
*/
private final ConcurrentMap<Class<?>, String> cachedNames = new ConcurrentHashMap<>();
/**
* 缓存了该 ExtensionLoader 加载的扩展名与扩展实现类之间的映射关系。cachedNames 集合的反向关系缓存
*/
private final Holder<Map<String, Class<?>>> cachedClasses = new Holder<>();
private final Map<String, Object> cachedActivates = new ConcurrentHashMap<>();
/**
* 缓存了该 ExtensionLoader 加载的扩展名与扩展实现对象之间的映射关系。
*/
private final ConcurrentMap<String, Holder<Object>> cachedInstances = new ConcurrentHashMap<>();
private final Holder<Object> cachedAdaptiveInstance = new Holder<>();
private volatile Class<?> cachedAdaptiveClass = null;
/**
* 记录了 type 这个扩展接口上 @SPI 注解的 value 值,也就是默认扩展名。
*/
private String cachedDefaultName;
private volatile Throwable createAdaptiveInstanceError;
private Set<Class<?>> cachedWrapperClasses;
private Map<String, IllegalStateException> exceptions = new ConcurrentHashMap<>();
private static volatile LoadingStrategy[] strategies = loadLoadingStrategies();
构造方法
private ExtensionLoader(Class<?> type) {
this.type = type;
//创建ExtensionFactory ,SPI加载ExtensionFactory也是扩展点
objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
}
//判断方法
private static <T> boolean withExtensionAnnotation(Class<T> type) {
//包含`@SPI`注解在接口上
return type.isAnnotationPresent(SPI.class);
}
getExtensionLoader
/**
* 根据扩展接口从 EXTENSION_LOADERS 缓存中查找相应的 ExtensionLoader 实例
*/
@SuppressWarnings("unchecked")
public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
//判断是否为NULL
if (type == null) {
throw new IllegalArgumentException("Extension type == null");
}
//不是接口就报错
if (!type.isInterface()) {
throw new IllegalArgumentException("Extension type (" + type + ") is not an interface!");
}
//判断 是否有扩展注解SPI,没有就报错 type.isAnnotationPresent(SPI.class);
if (!withExtensionAnnotation(type)) {
throw new IllegalArgumentException("Extension type (" + type +
") is not an extension, because it is NOT annotated with @" + SPI.class.getSimpleName() + "!");
}
/**
* 从缓存集合中获取对应的接口的ExtensionLoader
*/
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);
}
//返回ExtensionLoader
return loader;
}
getExtension
/**
* Find the extension with the given name. If the specified name is not found, then {@link IllegalStateException}
* will be thrown.
* 得到接口对应的 ExtensionLoader 对象之后会调用其 getExtension() 方法,根据传入的扩展名称从 cachedInstances 缓存中查找扩展实现的实例
*/
@SuppressWarnings("unchecked")
public T getExtension(String name) {
if (StringUtils.isEmpty(name)) {
//名称为空
throw new IllegalArgumentException("Extension name == null");
}
if ("true".equals(name)) {
//加载默认的扩展实现 如果name=true
return getDefaultExtension();
}
//getOrCreateHolder()方法中封装了查找cachedInstances缓存的逻辑
final Holder<Object> holder = getOrCreateHolder(name);
Object instance = holder.get();
//double-check防止并发问题
if (instance == null) {
synchronized (holder) {
instance = holder.get();
if (instance == null) {
//根据扩展名从SPI配置文件中查找对应的扩展实现类
instance = createExtension(name);
holder.set(instance);
}
}
}
return (T) instance;
}
getOrDefaultExtension
public T getOrDefaultExtension(String name) {
//获取默认
return containsExtension(name) ? getExtension(name) : getDefaultExtension();
}
/**
*获取默认的扩展类
*/
public T getDefaultExtension() {
//获取扩展类
getExtensionClasses();
if (StringUtils.isBlank(cachedDefaultName) || "true".equals(cachedDefaultName)) {
return null;
}
return getExtension(cachedDefaultName);
}
//判断是否存在
public boolean hasExtension(String name) {
if (StringUtils.isEmpty(name)) {
throw new IllegalArgumentException("Extension name == null");
}
//根据名称获取扩展类
Class<?> c = this.getExtensionClass(name);
return c != null;
}
getExtensionClasses
private Map<String, Class<?>> getExtensionClasses() {
//从缓存中获取 ExtensionLoader 加载的扩展名与扩展实现类之间的映射关系。cachedNames 集合的反向关系缓存
Map<String, Class<?>> classes = cachedClasses.get();
if (classes == null) {
synchronized (cachedClasses) {
classes = cachedClasses.get();
if (classes == null) {
//加载配置文件
classes = loadExtensionClasses();
cachedClasses.set(classes);
}
}
}
return classes;
}
构造中获取
objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
/**
* ExtensionFactory
* 根据 传入的扩展点类型,名称 获取扩展实现 与SPI中的名称挂钩
* adaptive=org.apache.dubbo.common.extension.factory.AdaptiveExtensionFactory
* spi=org.apache.dubbo.common.extension.factory.SpiExtensionFactory
* dubbo-common/src/main/resources/METAINF/dubbo/internal/org.apache.dubbo.common.extension.ExtensionFactory 中看到,他默认实现
*/
@SPI
public interface ExtensionFactory {
/**
* Get extension.
*
* @param type object type.
* @param name object name.
* @return object instance.
*/
<T> T getExtension(Class<T> type, String name);
}
getAdaptiveExtension
public T getAdaptiveExtension() {
//从缓存中获取
Object instance = cachedAdaptiveInstance.get();
if (instance == null) {
//为空判断有没有错误
if (createAdaptiveInstanceError != null) {
throw new IllegalStateException("Failed to create adaptive instance: " +
createAdaptiveInstanceError.toString(),
createAdaptiveInstanceError);
}
//加锁
synchronized (cachedAdaptiveInstance) {
//再次从缓存中获取
instance = cachedAdaptiveInstance.get();
if (instance == null) {
try {
//创建AdaptiveExtension
instance = createAdaptiveExtension();
//放入缓存
cachedAdaptiveInstance.set(instance);
} catch (Throwable t) {
createAdaptiveInstanceError = t;
throw new IllegalStateException("Failed to create adaptive instance: " + t.toString(), t);
}
}
}
}
return (T) instance;
}
AdaptiveExtensionFactory
- SpiExtensionFactory
public class SpiExtensionFactory implements ExtensionFactory {
@Override
public <T> T getExtension(Class<T> type, String name) {
//判断是否为接口,是否有SPI注解
if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
// 查找type对应的ExtensionLoader实例
ExtensionLoader<T> loader = ExtensionLoader.getExtensionLoader(type);
if (!loader.getSupportedExtensions().isEmpty()) {
//获取适配器实现
return loader.getAdaptiveExtension();
}
}
return null;
}
}
- SpringExtensionFactory
@Override
@SuppressWarnings("unchecked")
public <T> T getExtension(Class<T> type, String name) {
//SPI should be get from SpiExtensionFactory
if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
//如果是接口,并且有SPI注解,就使用SpiExtensionFactory获取
return null;
}
for (ApplicationContext context : CONTEXTS) {
//从Spring BeanFactory中获取对应的Bean实现
T bean = BeanFactoryUtils.getOptionalBean(context, name, type);
if (bean != null) {
return bean;
}
}
logger.warn("No spring extension (bean) named:" + name + ", try to find an extension (bean) of type " + type.getName());
return null;
}
- AdaptiveExtensionFactory 这个类加了Adaptive注解
@Adaptive
public class AdaptiveExtensionFactory implements ExtensionFactory {
private final List<ExtensionFactory> factories;
public AdaptiveExtensionFactory() {
//获取针对ExtensionFactory扩展加载器 org.apache.dubbo.common.extension.factory.AdaptiveExtensionFactory
ExtensionLoader<ExtensionFactory> loader = ExtensionLoader.getExtensionLoader(ExtensionFactory.class);
List<ExtensionFactory> list = new ArrayList<ExtensionFactory>();
//获取支持的扩展
for (String name : loader.getSupportedExtensions()) {
list.add(loader.getExtension(name));
}
factories = Collections.unmodifiableList(list);
}
@Override
public <T> T getExtension(Class<T> type, String name) {
for (ExtensionFactory factory : factories) {
T extension = factory.getExtension(type, name);
if (extension != null) {
return extension;
}
}
return null;
}
}
- 获取所有支持
//得到支持的扩展
public Set<String> getSupportedExtensions() {
Map<String, Class<?>> clazzes = getExtensionClasses();
//获取扩展点的名称
return Collections.unmodifiableSet(new TreeSet<>(clazzes.keySet()));
}
getExtensionClasses
private Map<String, Class<?>> getExtensionClasses() {
//从缓存中获取 ExtensionLoader 加载的扩展名与扩展实现类之间的映射关系。cachedNames 集合的反向关系缓存
Map<String, Class<?>> classes = cachedClasses.get();
if (classes == null) {
synchronized (cachedClasses) {
classes = cachedClasses.get();
if (classes == null) {
//加载配置文件
classes = loadExtensionClasses();
cachedClasses.set(classes);
}
}
}
return classes;
}
loadExtensionClasses
/**
* synchronized in getExtensionClasses 同步加载
*/
private Map<String, Class<?>> loadExtensionClasses() {
//获取默认的扩展实现名称
cacheDefaultExtensionName();
//创建一个窗口
Map<String, Class<?>> extensionClasses = new HashMap<>();
/**
* META-INF/dubbo/
* META-INF/dubbo/internal/
* META-INF/services/
* 根据不同的加载策略去不同的文件夹下加载扩展
*/
for (LoadingStrategy strategy : strategies) {
loadDirectory(extensionClasses, strategy.directory(), type.getName(), strategy.preferExtensionClassLoader(), strategy.overridden(), strategy.excludedPackages());
loadDirectory(extensionClasses, strategy.directory(), type.getName().replace("org.apache", "com.alibaba"), strategy.preferExtensionClassLoader(), strategy.overridden(), strategy.excludedPackages());
}
return extensionClasses;
}
cacheDefaultExtensionName
private void cacheDefaultExtensionName() {
//获取注解类中上的SPI注解
final SPI defaultAnnotation = type.getAnnotation(SPI.class);
if (defaultAnnotation == null) {
return;
}
//获取默认值SPI注解中的值 如@SPI("dubbo") @SPI(RandomLoadBalance.NAME) random
String value = defaultAnnotation.value();
if ((value = value.trim()).length() > 0) {
String[] names = NAME_SEPARATOR.split(value);
if (names.length > 1) {
throw new IllegalStateException("More than 1 default extension name on extension " + type.getName()
+ ": " + Arrays.toString(names));
}
if (names.length == 1) {
//获取名称
cachedDefaultName = names[0];
}
}
}
loadDirectory
/**
* META-INF/dubbo/
* META-INF/dubbo/internal/
* META-INF/services/
* 从上面指定的位置加载扩展信息
* 从这个文件夹中寻找真正的文件列表,并且对其中
* 的文件内容解析并且放入到 extensionClasses Map中
* dir META-INF/dubbo/internal/ 上面的路径
* type 类的接口全路径 org.apache.dubbo.common.extension.ExtensionFactory
*/
private void loadDirectory(Map<String, Class<?>> extensionClasses, String dir, String type,
boolean extensionLoaderClassLoaderFirst, boolean overridden, String... excludedPackages) {
//文件名称规则: 路径/包名.接口名
//META-INF/dubbo/internal/org.apache.dubbo.common.extension.ExtensionFactory
String fileName = dir + type;
try {
//寻找classloader和url列表
Enumeration<java.net.URL> urls = null;
//ClassUtils.getClassLoader(ExtensionLoader.class)
ClassLoader classLoader = findClassLoader();
// try to load from ExtensionLoader's ClassLoader first
if (extensionLoaderClassLoaderFirst) {
//如果需要的话, 需要先从当前类的ClassLoader中寻找
ClassLoader extensionLoaderClassLoader = ExtensionLoader.class.getClassLoader();
if (ClassLoader.getSystemClassLoader() != extensionLoaderClassLoader) {
urls = extensionLoaderClassLoader.getResources(fileName);
}
}
//如果找不到任何的URL列表,则继续尝试去其当前线程的ClassLoader中寻找
if (urls == null || !urls.hasMoreElements()) {
if (classLoader != null) {
urls = classLoader.getResources(fileName);
} else {
urls = ClassLoader.getSystemResources(fileName);
}
}
//如果存在文件的话
if (urls != null) {
while (urls.hasMoreElements()) {
java.net.URL resourceURL = urls.nextElement();
//遍历每一个资源文件,并且进行加载资源信息到extensionClasses, 主要功能是读取文件内容
loadResource(extensionClasses, classLoader, resourceURL, overridden, excludedPackages);
}
}
} catch (Throwable t) {
logger.error("Exception occurred when loading extension class (interface: " +
type + ", description file: " + fileName + ").", t);
}
}
loadResource
//用于读取文件操作,并且将方法交由 loadClass 来加载类信息。加载类信息也是最重要的
private void loadResource(Map<String, Class<?>> extensionClasses, ClassLoader classLoader,
java.net.URL resourceURL, boolean overridden, String... excludedPackages) {
try {
//读取文件
try (BufferedReader reader = new BufferedReader(new InputStreamReader(resourceURL.openStream(), StandardCharsets.UTF_8))) {
String line;
//一次读一行
while ((line = reader.readLine()) != null) {
//判断 是有#号有注释 不要
final int ci = line.indexOf('#');
//如果有
if (ci >= 0) {
//截取#号前面的
line = line.substring(0, ci);
}
//判断line是否》0,有内容
line = line.trim();
if (line.length() > 0) {
try {
String name = null;
//分割
int i = line.indexOf('=');
//大于0有=号
if (i > 0) {
//=前是名称
name = line.substring(0, i).trim();
//=号后面是实现类的全路径
line = line.substring(i + 1).trim();
}
if (line.length() > 0 && !isExcluded(line, excludedPackages)) {
//加载类 对类信息进行加载操作
loadClass(extensionClasses, resourceURL, Class.forName(line, true, classLoader), name, overridden);
}
} catch (Throwable t) {
IllegalStateException e = new IllegalStateException("Failed to load extension class (interface: " + type + ", class line: " + line + ") in " + resourceURL + ", cause: " + t.getMessage(), t);
exceptions.put(line, e);
}
}
}
}
} catch (Throwable t) {
logger.error("Exception occurred when loading extension class (interface: " +
type + ", class file: " + resourceURL + ") in " + resourceURL, t);
}
}
loadClass
//最终进行完成类映射的地方
private void loadClass(Map<String, Class<?>> extensionClasses, java.net.URL resourceURL, Class<?> clazz, String name,
boolean overridden) throws NoSuchMethodException {
//当前扩展点的实现,必须是当前扩展接口的实现才可以
if (!type.isAssignableFrom(clazz)) {
throw new IllegalStateException("Error occurred when loading extension class (interface: " +
type + ", class line: " + clazz.getName() + "), class "
+ clazz.getName() + " is not subtype of interface.");
}
//判断当前类是否有Adaptive注释
//如果是包含了Adaptive注解,则认为是需要对扩展点包装的方法,这里只做了存储操作,存储至cachedAdaptiveClass中
if (clazz.isAnnotationPresent(Adaptive.class)) {
cacheAdaptiveClass(clazz, overridden);
} else if (isWrapperClass(clazz)) {
// 判断是否是wapper类型, 是否构造函数中有该接口类型的传入
// wrapper类型的意思是,对当前的扩展点实现封装功能处理
cacheWrapperClass(clazz);
} else {
//创建实例
//找他是否已经定义过了名称, 主要是获取当前类的
//org.apache.dubbo.common.Extension注解,如果有的话就使用这个名称,否则的话就是用当前类的简单名称
clazz.getConstructor();
if (StringUtils.isEmpty(name)) {
//获取注释中的名称
name = findAnnotationName(clazz);
if (name.length() == 0) {
throw new IllegalStateException("No such extension name for the class " + clazz.getName() + " in the config " + resourceURL);
}
}
//否则的话,就对这个名称和class做映射关系
String[] names = NAME_SEPARATOR.split(name);
if (ArrayUtils.isNotEmpty(names)) {
//如果当前类拥有Activate注解,则将其进行添加到cachedActivates对象中,意味着需要执行
cacheActivateClass(clazz, names[0]);
for (String n : names) {
//进行名称映射保存
cacheName(clazz, n);
saveInExtensionClass(extensionClasses, clazz, n, overridden);
}
}
}
}
当执行完这几个方法之后,会对一下几个字段进行更新
- cachedAdaptiveClass: 当前Extension类型对应的AdaptiveExtension类型(只能一个)
- cachedWrapperClasses: 当前Extension类型对应的所有Wrapper实现类型(无顺序)
- cachedActivates: 当前Extension实现自动激活实现缓存(map,无序)
- cachedNames: 扩展点实现类对应的名称(如配置多个名称则值为第一个)
根据name获取扩展点的方法 getExtension
* 得到接口对应的 ExtensionLoader 对象之后会调用其 getExtension() 方法,根据传入的扩展名称从 cachedInstances 缓存中查找扩展实现的实例
*/
@SuppressWarnings("unchecked")
public T getExtension(String name) {
if (StringUtils.isEmpty(name)) {
//名称为空
throw new IllegalArgumentException("Extension name == null");
}
if ("true".equals(name)) {
//加载默认的扩展实现 如果name=true
return getDefaultExtension();
}
//getOrCreateHolder()方法中封装了查找cachedInstances缓存的逻辑
//获取当前类的holder,实现原理和cachedClasses的方式相同,都是建立同一个引用后再进行
//加锁
final Holder<Object> holder = getOrCreateHolder(name);
Object instance = holder.get();
//double-check防止并发问题
if (instance == null) {
synchronized (holder) {
instance = holder.get();
if (instance == null) {
//根据扩展名从SPI配置文件中查找对应的扩展实现类
//真正进行创建实例
instance = createExtension(name);
holder.set(instance);
}
}
}
return (T) instance;
}
getOrCreateHolder 是如何保证缓存的
public class Holder<T> {
private volatile T value;
public void set(T value) {
this.value = value;
}
public T get() {
return value;
}
}
private Holder<Object> getOrCreateHolder(String name) {
//根据名称获取实现
Holder<Object> holder = cachedInstances.get(name);
if (holder == null) {
//为空就创建一个放入缓存中
cachedInstances.putIfAbsent(name, new Holder<>());
//再获取出来
holder = cachedInstances.get(name);
}
return holder;
}
createExtension 的实现,他是具体根据扩展的class名称来进行创建实例的
类
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) {
//没有的话,同样适用putIfAbsent的方式来保证只会创建一个对象并且保存
EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.newInstance());
instance = (T) EXTENSION_INSTANCES.get(clazz);
}
// 注入其他扩展点的实体,用于扩展点和其他的扩展点相互打通
injectExtension(instance);
Set<Class<?>> wrapperClasses = cachedWrapperClasses;
if (CollectionUtils.isNotEmpty(wrapperClasses)) {
for (Class<?> wrapperClass : wrapperClasses) {
//进行遍历所有的包装类信息,分别对包装的类进行包装实例化,并且返回自身引用
// 同样进行注册其他扩展点的功能
instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
}
}
//对扩展点进行初始化操作
initExtension(instance);
return instance;
} catch (Throwable t) {
throw new IllegalStateException("Extension instance (name: " + name + ", class: " +
type + ") couldn't be instantiated: " + t.getMessage(), t);
}
}
injectExtension
private T injectExtension(T instance) {
//检测objectFactory字段
if (objectFactory == null) {
return instance;
}
try {
//遍历其中的所有方法
for (Method method : instance.getClass().getMethods()) {
//方法遍历判断是否为setter方法 如果不是,忽略该方法继续下一个方法
if (!isSetter(method)) {
// 是否是set方法
// 1. 以"set"开头
// 2. 参数长度为1
// 3. 是公开的方法
continue;
}
/**
* Check {@link DisableInject} to see if we need auto injection for this property
*/
if (method.getAnnotation(DisableInject.class) != null) {
//判断是否禁止注入 如果方法上明确标注了@DisableInject注解,忽略该方法
continue;
}
//根据setter方法的参数,确定扩展接口
Class<?> pt = method.getParameterTypes()[0];
//判断是否为基本类型 原始类型(boolean、char、byte、short、int、long、float、double)
//如果参数为简单类型,忽略该setter方法(略)
if (ReflectUtils.isPrimitives(pt)) {
continue;
}
try {
//setter方法注入 获取需要set的扩展点名称
String property = getSetterProperty(method);
//从扩展中获取对象 加载并实例化扩展实现类
Object object = objectFactory.getExtension(pt, property);
//从ExtensionLoader中加载指定的扩展点
比如有一个方法为setRandom(LoadBalance loadBalance),那么则以为着需要加载负载均衡中名为random的扩展点
if (object != null) {
method.invoke(instance, object);
}
} catch (Exception e) {
logger.error("Failed to inject via method " + method.getName()
+ " of interface " + type.getName() + ": " + e.getMessage(), e);
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return instance;
}
- initExtension 展点进行初始化操作
private void initExtension(T instance) {
if (instance instanceof Lifecycle) {
Lifecycle lifecycle = (Lifecycle) instance;
lifecycle.initialize();
}
}