Dubbo-SPI系列文章目录
Dubbo-SPI(一)-加载机制概述
Dubbo-SPI(二)-@SPI注解
Dubbo-SPI(三)-getExtension实现原理
Dubbo-SPI(四)-@Adaptive注解
Dubbo-SPI(五)-@Activate注解
文章目录
- Dubbo-SPI系列文章目录
- ExtensionLoader工作原理
- 工作流程
- getExtension实现原理
- 入口
- 1.getDefaultExtension-获取默认扩展的实例
- 2.getExtensionClasses-获取扩展类
- 3.loadExtensionClasses-加载扩展类
- 4.cacheDefaultExtensionName-缓存默认扩展名
- 5.type的设置
- 6.loadExtensionClasses中的strategies
- 7.loadDirectory-加载配置文件目录
- 8.loadResource-加载资源
- 9.loadClass-加载扩展类
- 10.findAnnotationName-查询注解名称
- 11.cacheActivateClass-处理自动激活扩展缓存
- 12.cacheName-处理扩展类与扩展名缓存
- 13.saveInExtensionClass-保存扩展类到extensionClasses集合
- 14.cacheAdaptiveClass-处理自适应扩展缓存
- 15.cacheWrapperClass-处理包装扩展
- 16.阶段小结
- 17.getOrCreateHolder-创建/获取Holder对象
- 18.createExtension-创建扩展实例
- 19.injectExtension-注入扩展实例
- 20.initExtension-初始化扩展实例
ExtensionLoader工作原理
ExtensionLoader 类似 JDK标准SPI里的ServiceLoader类
代码ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension()
的作用是 获取 Protocol接口 的 适配器类
工作流程
ExtensionLoader的逻辑入口可以分为三个
- getExtension 获取普通扩展类
- getAdaptiveExtension 获取自动适应扩展类
- getActivateExtension 获取自动激活扩展类
三个入口中,getActivateExtension 对 getExtension 的依赖比较重,getAdaptiveExtension 则相对独立
getExtension 是 整个扩展器中 最核心的方法,实现了 一个完成的 普通扩展类的加载过程。
加载过程的每一步,都会先检查缓存中 是否已存在所需要的数据,如果存在则直接从缓存读取,没有则重新加载。
这个方法(getExtension) 每次只会 根据名称 返回一个 扩展点实现类
getExtension 初始化过程可以分为四步:
- 框架 读取 SPI(扩展点)对应下的路径配置文件,并根据配置 加载 所有 扩展类缓存(不初始化)
- 根据 传入的名称 初始化 对应扩展类
- 尝试查找 符合条件的包装类:包含扩展点的setter方法;包含扩展点类型相同的构造函数,为其注入扩展类实例
- 返回对应的扩展类实例
getAdaptiveExtension 只有加载配置信息部分 和 getExtension 共用一个方法,同样的,也会先检查缓存中是否存在 已经初始化好的Adaptive实例,没有 则 调用createAdaptiveExtension重新初始化
getAdaptiveExtension 初始化过程分为四步:
- 和getExtension 一样先加载配置文件
- 生成 自适应扩展类的代码字符串
- 获取 类加载器 和 编译器,并编译2生成的代码字符串
- 返回对应的 自适应扩展类实例
getExtension实现原理
入口
// 入参name是指定的扩展名
public T getExtension(String name) {
// 第二个参数:wrap-是否包装
return getExtension(name, true);
}
public T getExtension(String name, boolean wrap) {
if (StringUtils.isEmpty(name)) {
throw new IllegalArgumentException("Extension name == null");
}
// 如果name=true,返回 默认扩展类 的 实例
// 这里可能返回null
if ("true".equals(name)) {
return getDefaultExtension();
}
// 根据 扩展名 创建持有(扩展类)实例的 Holder对象
final Holder<Object> holder = getOrCreateHolder(name);
Object instance = holder.get();
if (instance == null) {
synchronized (holder) {
instance = holder.get();
if (instance == null) {
// 创建 扩展实例
instance = createExtension(name, wrap);
holder.set(instance);
}
}
}
// 返回扩展实例
return (T) instance;
}
1.getDefaultExtension-获取默认扩展的实例
// 缓存 默认扩展名
private String cachedDefaultName;
public T getDefaultExtension() {
// 获取 扩展类
getExtensionClasses();
// 如果 默认的扩展名 为空 或 =true,返回null
if (StringUtils.isBlank(cachedDefaultName) || "true".equals(cachedDefaultName)) {
return null;
}
// 根据 默认的扩展名 获取 扩展实例
return getExtension(cachedDefaultName);
}
2.getExtensionClasses-获取扩展类
// 普通扩展类(的)缓存,其实是一个map
// 缓存的是Class类型的对象
private final Holder<Map<String, Class<?>>> cachedClasses = new Holder<>();
private Map<String, Class<?>> getExtensionClasses() {
// 从cachedClasses中获取缓存集合,如果没有,对cachedClasses加同步锁后再获取,如果还没有,走loadExtensionClasses获取扩展类,放入cachedClasses
Map<String, Class<?>> classes = cachedClasses.get();
if (classes == null) {
synchronized (cachedClasses) {
classes = cachedClasses.get();
if (classes == null) {
// 加载扩展类
classes = loadExtensionClasses();
// 设置 普通扩展类 缓存
cachedClasses.set(classes);
}
}
}
return classes;
}
3.loadExtensionClasses-加载扩展类
/**
* synchronized in getExtensionClasses
* 同步方法
*/
private Map<String, Class<?>> loadExtensionClasses() {
// 缓存 默认的扩展名
cacheDefaultExtensionName();
Map<String, Class<?>> extensionClasses = new HashMap<>();
// 循环 所有策略加载的实现类,放到extensionClasses这个map中
for (LoadingStrategy strategy : strategies) {
loadDirectory(extensionClasses,
// 目录
strategy.directory(),
// 扩展接口全路径类名
type.getName(),
// 是否优先通过extensionLoaderClass加载
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;
}
4.cacheDefaultExtensionName-缓存默认扩展名
// 默认扩展名缓存
private String cachedDefaultName;
private void cacheDefaultExtensionName() {
// 检测当前扩展接口是否使用了SPI注解,如果没有SPI注解返回NULL
final SPI defaultAnnotation = type.getAnnotation(SPI.class);
if (defaultAnnotation == null) {
return;
}
// 获取SPI注解的value值!!!
// 去掉空格,用,来分割,如果>1个,则抛出异常
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));
}
// 用SPI注解的value值 设置为 当前扩展接口(type) 的 默认的扩展名 到 cachedDefaultName缓存中
if (names.length == 1) {
cachedDefaultName = names[0];
}
}
}
5.type的设置
type是在ExtensionLoader的构造方法中被设置的
而 ExtensionLoader的构造方法 会在 getExtensionLoader方法中被调用
private final Class<?> type;
// 这是一个私有方法,只能被getExtensionLoader方法调用
// 所以针对每一个扩展类,只会有一个ExtensionLoader
private ExtensionLoader(Class<?> type) {
// 使用@SPI注解的扩展接口
this.type = type;
// 如果扩展接口 是ExtensionFactory类型,那么objectFactory设置为null
// 如果扩展接口不是ExtensionFactory类型,获取一个ExtensionFactory接口的自适应扩展实例,赋值给objectFactory
// 每个Extension只能有一个@Adaptive自适应类型的实现,如果没有,dubbo会动态生成一个类
objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
}
// getExtensionLoader方法
public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
// ...
// 判断扩展接口是否使用了SPI注解
if (!withExtensionAnnotation(type)) {
throw new IllegalArgumentException("Extension type (" + type +
") is not an extension, because it is NOT annotated with @" + SPI.class.getSimpleName() + "!");
}
// 先从EXTENSION_LOADERS缓存中获取,如果没有,new一个构造参数=type的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);
}
return loader;
}
// 扩展类 与 该扩展类对应的ExtensionLoader 缓存
private static final ConcurrentMap<Class<?>, ExtensionLoader<?>> EXTENSION_LOADERS = new ConcurrentHashMap<>(64);
private static <T> boolean withExtensionAnnotation(Class<T> type) {
// 判断当前扩展接口是否使用了SPI注解
return type.isAnnotationPresent(SPI.class);
}
6.loadExtensionClasses中的strategies
loadExtensionClasses中的loadDirectory是基于loadLoadingStrategies方法设置的strategies数据进行循环的
private static volatile LoadingStrategy[] strategies = loadLoadingStrategies();
/**
* Load all {@link Prioritized prioritized} {@link LoadingStrategy Loading Strategies} via {@link ServiceLoader}
* 加载所有的策略配置的实现类,进行排序,返回一个新数组
* LoadingStrategy接口有4个实现
* DubboLoadingStrategy-META-INF/dubbo/
* DubboInternalLoadingStrategy-META-INF/dubbo/internal/
* DubboExternalLoadingStrategy-META-INF/dubbo/external/
* ServicesLoadingStrategy-META-INF/services/
*
* DubboInternalLoadingStrategy不循允许覆盖,其他都允许覆盖
* @return non-null
* @since 2.7.7
*/
private static LoadingStrategy[] loadLoadingStrategies() {
// load方法通过ServiceLoader.load加载了LoadingStrategy接口的所有实现类
// LoadingStrategy接口继承了Prioritized接口
// Prioritized接口继承了Comparable泛型接口,其中compareTo方法的实现是使用getPriority的返回值进行比对
// 所以LoadingStrategy排序是根据getPriority方法的返回值进行处理的
return stream(load(LoadingStrategy.class).spliterator(), false)
.sorted()
.toArray(LoadingStrategy[]::new);
}
7.loadDirectory-加载配置文件目录
回到loadExtensionClasses,继续看loadDirectory
/**
*
* @param extensionClasses 最后要保存的集合
* @param dir 配置文件路径
* @param type 扩展接口全路径类名
* @param extensionLoaderClassLoaderFirst 是否优先通过extensionLoaderClass加载
* @param overridden 是否覆盖
* @param excludedPackages 排除包
*/
private void loadDirectory(Map<String, Class<?>> extensionClasses, String dir, String type,
boolean extensionLoaderClassLoaderFirst, boolean overridden, String... excludedPackages) {
// 获取文件在项目中的路径
// META-INF/dubbo/扩展接口全路径类名
String fileName = dir + type;
try {
Enumeration<java.net.URL> urls = null;
// 获取ExtensionLoader的类加载器
ClassLoader classLoader = findClassLoader();
// try to load from ExtensionLoader's ClassLoader first
// 尝试优先通过ExtensionLoader的类加载器 进行加载资源文件
// 目前extensionLoaderClassLoaderFirst都是false
if (extensionLoaderClassLoaderFirst) {
// 先获取ExtensionLoader的类加载器
ClassLoader extensionLoaderClassLoader = ExtensionLoader.class.getClassLoader();
// 如果 系统加载器 != ExtensionLoader的类加载器,则用ExtensionLoader的类加载器 获取资源文件
if (ClassLoader.getSystemClassLoader() != extensionLoaderClassLoader) {
urls = extensionLoaderClassLoader.getResources(fileName);
}
}
// 加载当前fileName文件
// TODO getResources 和 getSystemResources的区别?
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();
loadResource(extensionClasses, classLoader, resourceURL, overridden, excludedPackages);
}
}
} catch (Throwable t) {
logger.error("Exception occurred when loading extension class (interface: " +
type + ", description file: " + fileName + ").", t);
}
}
private static ClassLoader findClassLoader() {
// 获取ExtensionLoader的类加载器
return ClassUtils.getClassLoader(ExtensionLoader.class);
}
8.loadResource-加载资源
/**
*
* @param extensionClasses 最后要保存的集合
* @param classLoader 类加载器
* @param resourceURL 资源路径
* @param overridden 是否覆盖
* @param excludedPackages 排除包
*/
private void loadResource(Map<String, Class<?>> extensionClasses, ClassLoader classLoader,
java.net.URL resourceURL, boolean overridden, String... excludedPackages) {
try {
// 从resourceURL中进行读取
try (BufferedReader reader = new BufferedReader(new InputStreamReader(resourceURL.openStream(), StandardCharsets.UTF_8))) {
String line;
String clazz = null;
while ((line = reader.readLine()) != null) {
// 获取当前行中第一个 "#" 的位置索引,#之后的被认为都是是注释
final int ci = line.indexOf('#');
// 如果当前行存在 "#",则去除 "#" 之后的内容
if (ci >= 0) {
line = line.substring(0, ci);
}
line = line.trim();
if (line.length() > 0) {
try {
String name = null;
int i = line.indexOf('=');
if (i > 0) {
// =之前的作为扩展实现名
name = line.substring(0, i).trim();
// =之后的是扩展类的具体实现的全路径类名
clazz = line.substring(i + 1).trim();
} else {
// 没有=直接使用一整行作为扩展类的具体实现的全路径类名
clazz = line;
}
// 如果扩展类实现的全路径类名不为空 且 不在被排除的范围内,则进行加载类
// 先根据clazz字符串,使用classLoader 生成一个Class类型对象
// 然后再进行loadClass
if (StringUtils.isNotEmpty(clazz) && !isExcluded(clazz, excludedPackages)) {
loadClass(extensionClasses, resourceURL, Class.forName(clazz, 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);
}
}
9.loadClass-加载扩展类
/**
*
* @param extensionClasses 集合
* @param resourceURL 资源文件路径
* @param clazz 配置文件中扩展类实现的Class类型对象
* @param name 配置文件中的扩展实现名
* @param overridden 是否覆盖
* @throws NoSuchMethodException NoSuchMethodException
*/
private void loadClass(Map<String, Class<?>> extensionClasses, java.net.URL resourceURL, Class<?> clazz, String name,
boolean overridden) throws NoSuchMethodException {
// 判断扩展接口type是否是扩展类实现clazz的父类
// 也就是说判断扩展类实现clazz是否实现了扩展接口type
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
if (clazz.isAnnotationPresent(Adaptive.class)) {
// 缓存 自适应扩展类 到 cachedAdaptiveClass
cacheAdaptiveClass(clazz, overridden);
} else if (isWrapperClass(clazz)) { // 判断扩展类实现上是否是包装类
// 缓存 包装扩展类 到 cachedWrapperClasses
cacheWrapperClass(clazz);
} else {
// 尝试clazz是否有 无参构造方法
clazz.getConstructor();
if (StringUtils.isEmpty(name)) {
// 如果扩展实现名(配置文件中=前面的)为空,则获取扩展类实现上的 @Extension 注解的value值
// 如果@Extension的value也没有,则使用处理后的小写类名
name = findAnnotationName(clazz);
if (name.length() == 0) {
throw new IllegalStateException("No such extension name for the class " + clazz.getName() + " in the config " + resourceURL);
}
}
// 用,对name进行分割
// 这里要分割,是考虑到 自动激活的情况
// 自动激活 也是 普通扩展来的一种,只是会根据不同条件同时激活罢了
String[] names = NAME_SEPARATOR.split(name);
if (ArrayUtils.isNotEmpty(names)) {
// 缓存 扩展名 和 自动激活 到 cachedActivates
cacheActivateClass(clazz, names[0]);
for (String n : names) {
// 缓存 扩展类、扩展名 到 cachedNames
cacheName(clazz, n);
// 保存 扩展名、扩展类 到 extensionClasses集合中
saveInExtensionClass(extensionClasses, clazz, n, overridden);
}
}
}
}
10.findAnnotationName-查询注解名称
先过针对自适应扩展 和 包装扩展的判断处理,看下findAnnotationName 及后续流程
private String findAnnotationName(Class<?> clazz) {
// 尝试获取clazz上@Extension注解的value值
org.apache.dubbo.common.Extension extension = clazz.getAnnotation(org.apache.dubbo.common.Extension.class);
if (extension != null) {
return extension.value();
}
// 如果clazz没有@Extension注解,获取clazz的简写名称
String name = clazz.getSimpleName();
// 如果 clazz的简写名称 是以 扩展接口type的简写名称 为结束的,则对clazz的简写名称 进行截取
if (name.endsWith(type.getSimpleName())) {
name = name.substring(0, name.length() - type.getSimpleName().length());
}
// 转换成小写返回
return name.toLowerCase();
}
11.cacheActivateClass-处理自动激活扩展缓存
// 扩展名 与 自动激活 缓存
private final Map<String, Object> cachedActivates = new ConcurrentHashMap<>();
private void cacheActivateClass(Class<?> clazz, String name) {
// 判断扩展类实现上是否有自动激活注解
Activate activate = clazz.getAnnotation(Activate.class);
if (activate != null) {
// 缓存 扩展名 + 自动激活对象
cachedActivates.put(name, activate);
} else {
// support com.alibaba.dubbo.common.extension.Activate
com.alibaba.dubbo.common.extension.Activate oldActivate = clazz.getAnnotation(com.alibaba.dubbo.common.extension.Activate.class);
if (oldActivate != null) {
cachedActivates.put(name, oldActivate);
}
}
}
12.cacheName-处理扩展类与扩展名缓存
// 扩展类 与 扩展名 缓存
private final ConcurrentMap<Class<?>, String> cachedNames = new ConcurrentHashMap<>();
private void cacheName(Class<?> clazz, String name) {
if (!cachedNames.containsKey(clazz)) {
cachedNames.put(clazz, name);
}
}
13.saveInExtensionClass-保存扩展类到extensionClasses集合
private void saveInExtensionClass(Map<String, Class<?>> extensionClasses, Class<?> clazz, String name, boolean overridden) {
// 先在extensionClasses集合中根据name获取一下
Class<?> c = extensionClasses.get(name);
// 如果extensionClasses集合中没有 或者 允许覆盖,则进行put
if (c == null || overridden) {
extensionClasses.put(name, clazz);
} else if (c != clazz) {
// 如果extensionClasses集合有 或者 不允许覆盖,则抛出异常
String duplicateMsg = "Duplicate extension " + type.getName() + " name " + name + " on " + c.getName() + " and " + clazz.getName();
logger.error(duplicateMsg);
throw new IllegalStateException(duplicateMsg);
}
}
14.cacheAdaptiveClass-处理自适应扩展缓存
回过头来看loadClass中的cacheAdaptiveClass
// 自适应扩展类 缓存,只能同时存在一个
private volatile Class<?> cachedAdaptiveClass = null;
private void cacheAdaptiveClass(Class<?> clazz, boolean overridden) {
// 如果 自适应扩展类缓存cachedAdaptiveClass为空 或者 可以覆盖,则进行赋值
if (cachedAdaptiveClass == null || overridden) {
cachedAdaptiveClass = clazz;
} else if (!cachedAdaptiveClass.equals(clazz)) {
// 自适应扩展类缓存cachedAdaptiveClass 不等于 入参类clazz,则抛出异常
throw new IllegalStateException("More than 1 adaptive class found: "
+ cachedAdaptiveClass.getName()
+ ", " + clazz.getName());
}
}
15.cacheWrapperClass-处理包装扩展
// 包装扩展类 缓存,不可重复,集合中不能有重复的包装扩展类
private Set<Class<?>> cachedWrapperClasses;
private void cacheWrapperClass(Class<?> clazz) {
if (cachedWrapperClasses == null) {
cachedWrapperClasses = new ConcurrentHashSet<>();
}
cachedWrapperClasses.add(clazz);
}
16.阶段小结
到此,上面是getExtensionClasses方法中loadExtensionClasses方法的处理逻辑,完成之后得到的Map<String, Class<?>>放入普通扩展类缓存cachedClasses中
以上处理,仅仅是把扩展类的Class对象 加载到jvm中,并没有做Class初始化。在加载Class文件时,会根据Class上的注释 来判断扩展点类型,再根据类型分类 做缓存。
接下来回到getExtension方法中继续往下
17.getOrCreateHolder-创建/获取Holder对象
// getExtension中有这么一行
final Holder<Object> holder = getOrCreateHolder(name);
// 扩展名 与 扩展对象 缓存
private final ConcurrentMap<String, Holder<Object>> cachedInstances = new ConcurrentHashMap<>();
// 入参name是getExtension中指定的扩展名
private Holder<Object> getOrCreateHolder(String name) {
// 先从缓存中获取name对应的Holder,缓存中没有就new一个Holder
// 注意此时Holder对象的Object是空
Holder<Object> holder = cachedInstances.get(name);
if (holder == null) {
cachedInstances.putIfAbsent(name, new Holder<>());
holder = cachedInstances.get(name);
}
return holder;
}
// 回到getExtension中继续
// 如果holder中没有扩展实例,则走createExtension
Object instance = holder.get();
if (instance == null) {
synchronized (holder) {
instance = holder.get();
if (instance == null) {
instance = createExtension(name, wrap);
holder.set(instance);
}
}
}
return (T) instance;
18.createExtension-创建扩展实例
// 扩展类 与 扩展类初始化后的实例 缓存
private static final ConcurrentMap<Class<?>, Object> EXTENSION_INSTANCES = new ConcurrentHashMap<>(64);
private T createExtension(String name, boolean wrap) {
// 通过getExtensionClasses获得普通扩展类缓存
// 在缓存中查找指定name对应的普通扩展类缓存(类对象)
Class<?> clazz = getExtensionClasses().get(name);
if (clazz == null) {
throw findException(name);
}
try {
// 在缓存中查找 类对象 是否有对应的 类实例对象
T instance = (T) EXTENSION_INSTANCES.get(clazz);
// 如果不存在实例,就通过getDeclaredConstructor获取构造方法再newInstance,得到一个新实例,放到EXTENSION_INSTANCES缓存中
if (instance == null) {
EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.getDeclaredConstructor().newInstance());
instance = (T) EXTENSION_INSTANCES.get(clazz);
}
// 注入扩展类实例
injectExtension(instance);
// 如果wrap=true,要处理包装扩展类
if (wrap) {
List<Class<?>> wrapperClassesList = new ArrayList<>();
// 如果 包装扩展类缓存不为空,则加入到wrapperClassesList列表中,并排序、反转
if (cachedWrapperClasses != null) {
wrapperClassesList.addAll(cachedWrapperClasses);
wrapperClassesList.sort(WrapperComparator.COMPARATOR);
Collections.reverse(wrapperClassesList);
}
// 循环wrapperClassesList列表,得到Wrapper注解
if (CollectionUtils.isNotEmpty(wrapperClassesList)) {
for (Class<?> wrapperClass : wrapperClassesList) {
Wrapper wrapper = wrapperClass.getAnnotation(Wrapper.class);
// 如果包装类没有Wrapper注解 或
// 包装类的Wrapper注解的matches数组包含指定name 且 mismatches数组不包含指定name
if (wrapper == null
|| (ArrayUtils.contains(wrapper.matches(), name) && !ArrayUtils.contains(wrapper.mismatches(), name))) {
// 获取 包装类中参数类型为 扩展接口类型 的 构造方法,然后newInstance,把刚才实例化的扩展类传进去
// 再injectExtension(注入扩展),得到具体实例
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);
}
}
19.injectExtension-注入扩展实例
private final ExtensionFactory objectFactory;
private T injectExtension(T instance) {
if (objectFactory == null) {
return instance;
}
try {
// 循环扩展实例的方法
for (Method method : instance.getClass().getMethods()) {
// 如果不是setter方法则继续循环
if (!isSetter(method)) {
continue;
}
/**
* Check {@link DisableInject} to see if we need auto injection for this property
*/
// 如果方法上有DisableInject注解,则继续循环
if (method.getAnnotation(DisableInject.class) != null) {
continue;
}
// 获取方法的第一个参数的类型
Class<?> pt = method.getParameterTypes()[0];
// 如果方法的第一个参数不是基础类型,就继续循环
if (ReflectUtils.isPrimitives(pt)) {
continue;
}
// 所以走到这里的情况是set方法只有一个参数,并且参数是public的
try {
// 根据setXXX方法名,获取属性名称
String property = getSetterProperty(method);
// 这里主要是通过getExtension 寻找 与参数pt的Class类型相同的 且 名称相同的 扩展类实例,如果能找到,就通过invoke把找到的object设置进去
// objectFactory有三种实现,后面再说
Object object = objectFactory.getExtension(pt, property);
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;
}
// 根据setXXX方法名,获取属性名称
private String getSetterProperty(Method method) {
return method.getName().length() > 3 ? method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4) : "";
}
20.initExtension-初始化扩展实例
private void initExtension(T instance) {
if (instance instanceof Lifecycle) {
Lifecycle lifecycle = (Lifecycle) instance;
lifecycle.initialize();
}
}
到这里,getExtension方法才算全部执行完成