首先从获取拓展加载器说起
@Override
@SuppressWarnings("unchecked")
public ExtensionLoader getExtensionLoader(Class type) {
checkDestroyed();
if (type == null) {
throw new IllegalArgumentException("Extension type == null");
}
if (!type.isInterface()) {
throw new IllegalArgumentException("Extension type (" + type + ") is not an interface!");
}
if (!withExtensionAnnotation(type)) {
throw new IllegalArgumentException("Extension type (" + type +
") is not an extension, because it is NOT annotated with @" + SPI.class.getSimpleName() + "!");
}
// 1. find in local cache
ExtensionLoader loader = (ExtensionLoader) extensionLoadersMap.get(type);
ExtensionScope scope = extensionScopeMap.get(type);
if (scope == null) {
SPI annotation = type.getAnnotation(SPI.class);
scope = annotation.scope();
extensionScopeMap.put(type, scope);
}
if (loader == null && scope == ExtensionScope.SELF) {
// create an instance in self scope
loader = createExtensionLoader0(type);
}
// 2. find in parent
if (loader == null) {
if (this.parent != null) {
loader = this.parent.getExtensionLoader(type);
}
}
// 3. create it
if (loader == null) {
loader = createExtensionLoader(type);
}
return loader;
}
①首先去当前对象的extensionLoadersMap(ConcurrentHashMap)属性成员中获取是否有对应type Class类的加载器
②再到当前对象的extensionScopeMap(ConcurrentHashMap)属性成员中获取对应type Class的Spi注解scope属性范围
③如果没有,就去获取type Class上面的SPI注解
④拿到SPI注解中Scope的值(默认是ExtensionScope.APPLICATION)
⑤存入当前对象的extensionScopeMap(ConcurrentHashMap)属性成员中
⑥如果第①步拿到的成员是空,且第②步拿到的scope是self,则创建一个self的loader
⑦如果scope属性值不是self且属性成员parent不为空,那么到parent中取获取加载器
⑧如果还获取不到,那么开始创建loader
这里我们重点跟踪下第⑧部的默认创建loader步骤
privateExtensionLoader createExtensionLoader(Class type) { ExtensionLoader loader = null; if (isScopeMatched(type)) { // if scope is matched, just create it loader = createExtensionLoader0(type); } return loader; }
①检查下type Class上面的SPI注解里面的scope默认值是否和传进来的一致
②如果scope匹配,则开始创建
privateExtensionLoader createExtensionLoader0(Class type) { checkDestroyed(); ExtensionLoader loader; // ①直接通过new 一个ExtensionLoader对象(这里就会进行这个对象的一些初始化操作了,后续一些用到的属性都是在这个初始化操作完成的,我们后面遇到再重点提起) // ②存入当前对象成员属性extensionLoadersMap extensionLoadersMap.putIfAbsent(type, new ExtensionLoader (type, this, scopeModel)); // ③直接从当前对象成员属性extensionLoadersMap根据type获取对应的loader返回 loader = (ExtensionLoader ) extensionLoadersMap.get(type); return loader; }
①直接通过new 一个ExtensionLoader对象(这里就会进行这个对象的一些初始化操作了,后续一些用到的属性都是在这个初始化操作完成的,我们后面遇到再重点提起)
②存入当前对象成员属性extensionLoadersMap
③直接从当前对象成员属性extensionLoadersMap根据type获取对应的loader返回
好,此时我们已经拿到ExtensionLoader对象了,可以调用getExtension来获取对应实例
public T getExtension(String name) {
// ①根据名字及允许包装来获取实例
T extension = getExtension(name, true);
// ②如果没有获取到,则抛异常
if (extension == null) {
throw new IllegalArgumentException("Not find extension: " + name);
}
return extension;
}
①根据名字及允许包装来获取实例
②如果没有获取到,则抛异常
public T getExtension(String name, boolean wrap) {
checkDestroyed();
if (StringUtils.isEmpty(name)) {
throw new IllegalArgumentException("Extension name == null");
}
// ①如果name是"true"则获取默认的spi对象
if ("true".equals(name)) {
return getDefaultExtension();
}
// ②获取cacheKey,如果不允许包装,则通过拼接_origin来控制返回原对象
String cacheKey = name;
if (!wrap) {
cacheKey += "_origin";
}
// ③获取生成的cacheKey对应的holder
final Holder
①如果name是"true"则获取默认的spi对象
②获取cacheKey,如果不允许包装,则通过拼接_origin来控制返回原对象
③获取生成的cacheKey对应的holder
④从holder中获取是否有对应对象
⑤如果没有,对holder加锁双重检查后进行创建
⑥再将创建好的对象放进holder中
private T createExtension(String name, boolean wrap) {
// ①获取ExtensionClassMap(也就是每个name对应的class全路径名),再从map中获取name对应的class全类名
Class> clazz = getExtensionClasses().get(name);
if (clazz == null || unacceptableExceptions.contains(name)) {
throw findException(name);
}
try {
// ②先根据当前loader对象属性成员extensionInstances(ConcurrentHashMap)中根据类型去获取对象
T instance = (T) extensionInstances.get(clazz);
if (instance == null) {
//③如果没获取到,则根据class全类名创建实例,并放进当前loader对象属性成员extensionInstances(ConcurrentHashMap)中
extensionInstances.putIfAbsent(clazz, createExtensionInstance(clazz));
//④从当前loader对象属性成员extensionInstances(ConcurrentHashMap)中根据type对应的Class对象取出对应的实例
instance = (T) extensionInstances.get(clazz);
//⑤获取前置处理器,循环遍历调用
instance = postProcessBeforeInitialization(instance, name);
//⑥反射调用set方法将实例注入取出的实例属性
injectExtension(instance);
//⑦获取后置处理器,循环遍历调用
instance = postProcessAfterInitialization(instance, name);
}
//⑧如果需要包装,将cachedWrapperClasses的包装Class集合放进wrapperClassesList并排序
if (wrap) {
List> wrapperClassesList = new ArrayList<>();
if (cachedWrapperClasses != null) {
wrapperClassesList.addAll(cachedWrapperClasses);
wrapperClassesList.sort(WrapperComparator.COMPARATOR);
Collections.reverse(wrapperClassesList);
}
if (CollectionUtils.isNotEmpty(wrapperClassesList)) {
//⑨循环遍历所有的包装Class,判断是否有Wrapper注解,如果有则根据注解上面的配置匹配过滤下当前包装Class
// 是否适用当前name对应的对象
for (Class> wrapperClass : wrapperClassesList) {
Wrapper wrapper = wrapperClass.getAnnotation(Wrapper.class);
boolean match = (wrapper == null) ||
((ArrayUtils.isEmpty(wrapper.matches()) || ArrayUtils.contains(wrapper.matches(), name)) &&
!ArrayUtils.contains(wrapper.mismatches(), name));
if (match) {
//⑩如果匹配,拿到包装类 获取构造器 将被包装的类传入构造器反射 反射 创建实例,并注入其他属性返回
instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
instance = postProcessAfterInitialization(instance, name);
}
}
}
}
// 11.如果name对应的对象实现了Lifecycle接口,则调用器初始化方法,返回
// Warning: After an instance of Lifecycle is wrapped by cachedWrapperClasses, it may not still be Lifecycle instance, this application may not invoke the lifecycle.initialize hook.
initExtension(instance);
return instance;
} catch (Throwable t) {
throw new IllegalStateException("Extension instance (name: " + name + ", class: " +
type + ") couldn't be instantiated: " + t.getMessage(), t);
}
}
①获取ExtensionClassMap(也就是每个name对应的class全路径名),再从map中获取name对应的class全类名
②先根据当前loader对象属性成员extensionInstances(ConcurrentHashMap)中根据类型去获取对象
③如果没获取到,则根据class全类名创建实例,并放进当前loader对象属性成员extensionInstances(ConcurrentHashMap)中
④从当前loader对象属性成员extensionInstances(ConcurrentHashMap)中根据type对应的Class对象取出对应的实例
⑤获取前置处理器,循环遍历调用
⑥反射调用set方法将实例注入取出的实例属性
⑦获取后置处理器,循环遍历调用
⑧如果需要包装,将cachedWrapperClasses的包装Class集合放进wrapperClassesList并排序
⑨循环遍历所有的包装Class,判断是否有Wrapper注解,如果有则根据注解上面的配置匹配过滤下当前包装Class是否适用当前name对应的对象
⑩如果匹配,拿到包装类 获取构造器 将被包装的类传入构造器反射 反射 创建实例,并注入其他属性返回
11.如果name对应的对象实现了Lifecycle接口,则调用器初始化方法,创建完成
接下来,我们深入一些重点方法来细化一些流程
首先看下第①步中如何获取ExtensionClassMap
private Map> getExtensionClasses() { // ①先从当前loader对象的cachedClasses(Holder
①先从当前loader对象的cachedClasses(Holder
private Map> loadExtensionClasses() { checkDestroyed(); // ①设置当前loader对象默认的spi name,即给cachedDefaultName成员属性赋值 cacheDefaultExtensionName(); Map > extensionClasses = new HashMap<>(); // ②循环遍历所有的加载策略,将各个类加载器加载路径下以接口命名的文件中 // key(name),value(全类名)键值对加载进extensionClasses(Map >)中 for (LoadingStrategy strategy : strategies) { loadDirectory(extensionClasses, strategy, type.getName()); // compatible with old ExtensionFactory if (this.type == ExtensionInjector.class) { loadDirectory(extensionClasses, strategy, ExtensionFactory.class.getName()); } } return extensionClasses; }
①设置当前loader对象默认的spi name,即给cachedDefaultName成员属性赋值
②循环遍历所有的加载策略,将各个类加载器加载路径下以接口命名的文件中key(name),value(全类名)键值对加载进extensionClasses(Map
private void loadDirectory(Map> extensionClasses, LoadingStrategy strategy, String type) { // ①根据加载策略类加载type对应文件下的key,value loadDirectoryInternal(extensionClasses, strategy, type); try { // ②兼容行为,把type全类名的org.apache改为com.alibaba再去加载一遍对应文件中的key,value String oldType = type.replace("org.apache", "com.alibaba"); if (oldType.equals(type)) { return; } //if class not found,skip try to load resources ClassUtils.forName(oldType); loadDirectoryInternal(extensionClasses, strategy, oldType); } catch (ClassNotFoundException classNotFoundException) { } }
①根据加载策略类加载type对应文件下的key,value
②兼容行为,把type全类名的org.apache改为com.alibaba再去加载一遍对应文件中的key,value
private void loadDirectoryInternal(Map> extensionClasses, LoadingStrategy loadingStrategy, String type) { // ①根据策略类拼接好文件名 String fileName = loadingStrategy.directory() + type; try { List classLoadersToLoad = new LinkedList<>(); // try to load from ExtensionLoader's ClassLoader first if (loadingStrategy.preferExtensionClassLoader()) { ClassLoader extensionLoaderClassLoader = ExtensionLoader.class.getClassLoader(); if (ClassLoader.getSystemClassLoader() != extensionLoaderClassLoader) { classLoadersToLoad.add(extensionLoaderClassLoader); } } if (specialSPILoadingStrategyMap.containsKey(type)){ String internalDirectoryType = specialSPILoadingStrategyMap.get(type); //skip to load spi when name don't match if (!LoadingStrategy.ALL.equals(internalDirectoryType) && !internalDirectoryType.equals(loadingStrategy.getName())){ return; } classLoadersToLoad.clear(); classLoadersToLoad.add(ExtensionLoader.class.getClassLoader()); }else { // load from scope model Set classLoaders = scopeModel.getClassLoaders(); if (CollectionUtils.isEmpty(classLoaders)) { Enumeration resources = ClassLoader.getSystemResources(fileName); if (resources != null) { while (resources.hasMoreElements()) { //② 根据文件名对应到类加载器上的文件路径加载文件中的内容,name作为key,value对应的Class作为value设置进extensionClasses loadResource(extensionClasses, null, resources.nextElement(), loadingStrategy.overridden(), loadingStrategy.includedPackages(), loadingStrategy.excludedPackages(), loadingStrategy.onlyExtensionClassLoaderPackages()); } } } else { classLoadersToLoad.addAll(classLoaders); } } Map > resources = ClassLoaderResourceLoader.loadResources(fileName, classLoadersToLoad); resources.forEach(((classLoader, urls) -> { loadFromClass(extensionClasses, loadingStrategy.overridden(), urls, classLoader, loadingStrategy.includedPackages(), loadingStrategy.excludedPackages(), loadingStrategy.onlyExtensionClassLoaderPackages()); })); } catch (Throwable t) { logger.error("Exception occurred when loading extension class (interface: " + type + ", description file: " + fileName + ").", t); } }
①根据策略类拼接好文件名
② 根据文件名对应到类加载器上的文件路径加载文件中的内容,name作为key,value对应的Class作为value设置进extensionClasses
private void loadResource(Map> extensionClasses, ClassLoader classLoader, java.net.URL resourceURL, boolean overridden, String[] includedPackages, String[] excludedPackages, String[] onlyExtensionClassLoaderPackages) { try { // ①获取url对应文件中的内容,将每行数据作为一个元素塞进list中 List newContentList = getResourceContent(resourceURL); String clazz; // ②遍历每行数据,将等号左边的值作为name,右边的值Class.forName获取clazz作为value放进extensionClasses for (String line : newContentList) { 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; } if (StringUtils.isNotEmpty(clazz) && !isExcluded(clazz, excludedPackages) && isIncluded(clazz, includedPackages) && !isExcludedByClassLoader(clazz, classLoader, onlyExtensionClassLoaderPackages)) { 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); } }
①获取url对应文件中的内容,将每行数据作为一个元素塞进list中
②遍历每行数据,将等号左边的值作为name,右边的值Class.forName获取clazz作为value放进extensionClasses
private void loadClass(Map> extensionClasses, java.net.URL resourceURL, Class> clazz, String name, boolean overridden) { 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注解,如果有就将clazz赋值给当前loader对象的cachedAdaptiveClass属性 // ②如果是包装类,则将clazz塞进当前loader对象的cachedWrapperClasses(set)中 // ③如果都不是,则进行加载进extensionClasses if (clazz.isAnnotationPresent(Adaptive.class)) { cacheAdaptiveClass(clazz, overridden); } else if (isWrapperClass(clazz)) { cacheWrapperClass(clazz); } else { 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); } } String[] names = NAME_SEPARATOR.split(name); if (ArrayUtils.isNotEmpty(names)) { cacheActivateClass(clazz, names[0]); for (String n : names) { cacheName(clazz, n); saveInExtensionClass(extensionClasses, clazz, n, overridden); } } } }
①判断是否有Adaptive注解,如果有就将clazz赋值给当前loader对象的cachedAdaptiveClass属性
②如果是包装类,则将clazz塞进当前loader对象的cachedWrapperClasses(set)中
③如果都不是,则进行加载extensionClasses
private void saveInExtensionClass(Map> extensionClasses, Class> clazz, String name, boolean overridden) { Class> c = extensionClasses.get(name); if (c == null || overridden) { extensionClasses.put(name, clazz); } else if (c != clazz) { // duplicate implementation is unacceptable unacceptableExceptions.add(name); String duplicateMsg = "Duplicate extension " + type.getName() + " name " + name + " on " + c.getName() + " and " + clazz.getName(); logger.error(duplicateMsg); throw new IllegalStateException(duplicateMsg); } }
剥了这么多层洋葱,终于看到了put操作
此时我们就已经拿到了name对应的 clazz



