Dubbo-SPI原理

参考:https://mp.weixin.qq.com

官网地址:https://dubbo.apache.org/zh/docs/v2.7/dev/source/dubbo-spi/

双亲委托模式的弊端

  判断类是否加载的时候,应用类加载器会顺着双亲路径往上判断,直到启动类加载器.但是启动类加载器不会往下询问,这个委托路线是单向的,即顶层的类加载器,无法访问底层的类加载器所加载的类
  启动类加载器中的类为系统的核心类,比如,在系统类中,提供了一个接口,并且该接口还提供了一个工厂方法用于创建该接口的实例,但是该接口的实现类在应用层中,接口和工厂方法在启动类加载器中,就会出现工厂方法无法创建由应用类加载器加载的应用实例问题.

  拥有这样问题的组件有很多,比如JDBC(DataSource、Driver)、Xml parser等.JDBC本身是java连接数据库的一个标准,是进行数据库连接的抽象层,由java编写的一组类和接口组成,接口的实现由各个数据库厂商来完成

 文件内容com.mysql.cj.jdbc.Driver

双亲委托模式的补充 

  在Java中,把核心类(rt.jar)中提供外部服务,可由应用层自行实现的接口,这种方式成为spi

ExtensionLoader

  org.apache.dubbo.common.extension.ExtensionLoader#getExtension源码分析

public T getExtension(String name) {
	// 默认包装成Wrapper对象
	return getExtension(name, true);
}

public T getExtension(String name, boolean wrap) {
	if (StringUtils.isEmpty(name)) {
		throw new IllegalArgumentException("Extension name == null");
	}
	// 返回默认的扩展实现类
	if ("true".equals(name)) {
		return getDefaultExtension();
	}
	// volatile + synchronized + double-check 获取或创建扩展点实现类
	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;
}

  createExtension源码分析 

private T createExtension(String name, boolean wrap) {
	// 从配置文件中加载所有的拓展类,可得到“配置项名称”到“配置类”的映射关系表
	Class<?> clazz = getExtensionClasses().get(name);
	if (clazz == null) {
		// 抛出异常
		throw findException(name);
	}
	try {
		T instance = (T) EXTENSION_INSTANCES.get(clazz);
		if (instance == null) {
			// 通过反射创建实例
			EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.newInstance());
			instance = (T) EXTENSION_INSTANCES.get(clazz);
		}
		// 向实例中注入依赖,为变量赋值
		injectExtension(instance);

		if (wrap) {
			List<Class<?>> wrapperClassesList = new ArrayList<>();
			if (cachedWrapperClasses != null) {
				wrapperClassesList.addAll(cachedWrapperClasses);
                   // 根据Activate注解中的order属性值排序  wrapperClassesList.sort(WrapperComparator.COMPARATOR); Collections.reverse(wrapperClassesList); } // 循环创建 Wrapper 实例 if (CollectionUtils.isNotEmpty(wrapperClassesList)) { for (Class<?> wrapperClass : wrapperClassesList) { Wrapper wrapper = wrapperClass.getAnnotation(Wrapper.class); if (wrapper == null || (ArrayUtils.contains(wrapper.matches(), name) && !ArrayUtils.contains(wrapper.mismatches(), name))) { // 将当前 instance 作为参数传给 Wrapper 的构造方法,并通过反射创建 Wrapper 实例 // 然后向 Wrapper 实例中注入依赖,最后将 Wrapper 实例再次赋值给 instance 变量 instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance)); } } } } // 是否实现了 Lifecycle,生命周期的初始化处理 initExtension(instance); return instance; } catch (Throwable t) { throw new IllegalStateException("Extension instance (name: " + name + ", class: " + type + ") couldn't be instantiated: " + t.getMessage(), t); } }

  getExtensionClasses源码分析

private Map<String, Class<?>> getExtensionClasses() {
	// 从缓存中获取已加载的拓展类
	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源码分析

private Map<String, Class<?>> loadExtensionClasses() {
	// 对 SPI 注解进行解析,如果存在默认扩展名则获取并缓存
	cacheDefaultExtensionName();

	Map<String, Class<?>> extensionClasses = new HashMap<>();

	// 根据加载策略加载指定文件夹下的配置文件
	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;
}

private void cacheDefaultExtensionName() {
	// 获取 SPI 注解,这里的 type 变量是在调用 getExtensionLoader 方法时传入的
	final SPI defaultAnnotation = type.getAnnotation(SPI.class);
	if (defaultAnnotation == null) {
		return;
	}

	String value = defaultAnnotation.value();
	if ((value = value.trim()).length() > 0) {
		// 对 SPI 注解内容进行切分
		String[] names = NAME_SEPARATOR.split(value);
		// 检测 SPI 注解内容是否合法,不合法则抛出异常
		if (names.length > 1) {
			throw new IllegalStateException("More than 1 default extension name on extension " + type.getName()
					+ ": " + Arrays.toString(names));
		}
		// 设置默认名称,参考 getDefaultExtension 方法
		if (names.length == 1) {
			cachedDefaultName = names[0];
		}
	}
}

  loadDirectory源码分析  

private void loadDirectory(Map<String, Class<?>> extensionClasses, String dir, String type,
                               boolean extensionLoaderClassLoaderFirst, boolean overridden, String... excludedPackages) {
	// fileName = 文件夹路径 + type 全限定名
	String fileName = dir + type;
	try {
		Enumeration<java.net.URL> urls = null;
		ClassLoader classLoader = findClassLoader();

		// try to load from ExtensionLoader's ClassLoader first
		if (extensionLoaderClassLoaderFirst) {
			ClassLoader extensionLoaderClassLoader = ExtensionLoader.class.getClassLoader();
			if (ClassLoader.getSystemClassLoader() != extensionLoaderClassLoader) {
				urls = extensionLoaderClassLoader.getResources(fileName);
			}
		}

		// 根据文件名加载所有的同名文件
		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);
	}
}

  loadResource源码分析

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 = line.trim();
				if (line.length() > 0) {
					try {
						String name = null;
						int i = line.indexOf('=');
						if (i > 0) {
							// 以等于号 = 为界,截取键与值
							name = line.substring(0, i).trim();
							line = line.substring(i + 1).trim();
						}
						if (line.length() > 0 && !isExcluded(line, excludedPackages)) {
							// 加载类,并通过 loadClass 方法对类进行缓存
							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 注解
	if (clazz.isAnnotationPresent(Adaptive.class)) {
		// 设置 cachedAdaptiveClass缓存
		cacheAdaptiveClass(clazz, overridden);
	}
	// 检测 clazz 是否是 Wrapper 类型,判断依据是是否有当前 type 的有参构造器
	else if (isWrapperClass(clazz)) {
		// 存储 clazz 到 cachedWrapperClasses 缓存中
		cacheWrapperClass(clazz);
	}
	// 程序进入此分支,表明 clazz 是一个普通的拓展类
	else {
		// 检测 clazz 是否有默认的构造方法,如果没有,则抛出异常
		clazz.getConstructor();
		if (StringUtils.isEmpty(name)) {
			// 如果 name 为空,则尝试从 Extension 注解中获取 name,或使用小写的类名作为 name
			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)) {
			// 如果类上有 Activate 注解,则使用 names 数组的第一个元素作为键,
			// 存储 name 到 Activate 注解对象的映射关系
			cacheActivateClass(clazz, names[0]);
			for (String n : names) {
				// 存储 Class 到名称的映射关系
				cacheName(clazz, n);
				// 存储名称到 Class 的映射关系
				saveInExtensionClass(extensionClasses, clazz, n, overridden);
			}
		}
	}
}

IOC

  通过 setter 方法注入依赖,createExtension方法中执行完getExtensionClasses方法,从配置文件中加载完所有的拓展类后,获得了目标扩展实例,进行依赖注入

  injectExtension源码分析

private T injectExtension(T instance) {

	if (objectFactory == null) {
		return instance;
	}

	try {
		// 遍历目标类的所有方法
		for (Method method : instance.getClass().getMethods()) {
			// 检测方法是否以 set 开头,且方法仅有一个参数,且方法访问级别为 public
			if (!isSetter(method)) {
				continue;
			}
			/**
			 * Check {@link DisableInject} to see if we need auto injection for this property
			 */
			if (method.getAnnotation(DisableInject.class) != null) {
				continue;
			}
			// 获取 setter 方法参数类型
			Class<?> pt = method.getParameterTypes()[0];
			if (ReflectUtils.isPrimitives(pt)) {
				continue;
			}

			try {
				// 获取属性名,比如 setName 方法对应属性名 name
				String property = getSetterProperty(method);
				// 从 ObjectFactory 中获取依赖对象,SPI方式,Spring方式
				Object object = objectFactory.getExtension(pt, property);
				if (object != null) {
					// 通过反射调用 setter 方法设置依赖
					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;
} 

AOP 

  createExtension方法中

if (wrap) {

	List<Class<?>> wrapperClassesList = new ArrayList<>();
	if (cachedWrapperClasses != null) {
		wrapperClassesList.addAll(cachedWrapperClasses);
		// 根据Activate注解中的order属性值排序
		wrapperClassesList.sort(WrapperComparator.COMPARATOR);
		Collections.reverse(wrapperClassesList);
	}

	// 循环创建 Wrapper 实例
	if (CollectionUtils.isNotEmpty(wrapperClassesList)) {
		for (Class<?> wrapperClass : wrapperClassesList) {
			Wrapper wrapper = wrapperClass.getAnnotation(Wrapper.class);
			// Wrapper注解为空,或者不为空但是符合匹配条件
			if (wrapper == null
					|| (ArrayUtils.contains(wrapper.matches(), name) && !ArrayUtils.contains(wrapper.mismatches(), name))) {
				// 将当前 instance 作为参数传给 Wrapper 的构造方法,并通过反射创建 Wrapper 实例,实现了AOP
				// 然后向 Wrapper 实例中注入依赖,最后将 Wrapper 实例再次赋值给 instance 变量
				instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
			}
		}
	}
}

Adaptive

  getAdaptiveExtension源码分析 

public T getAdaptiveExtension() {
	Object instance = cachedAdaptiveInstance.get();
	if (instance == null) {
		// 并发情况下,如果有error直接报错,不去竞争锁了
		if (createAdaptiveInstanceError != null) {
			throw new IllegalStateException("Failed to create adaptive instance: " +
					createAdaptiveInstanceError.toString(),
					createAdaptiveInstanceError);
		}

		synchronized (cachedAdaptiveInstance) {
			instance = cachedAdaptiveInstance.get();
			if (instance == null) {
				try {
					// 创建Adaptive实例
					instance = createAdaptiveExtension();
					cachedAdaptiveInstance.set(instance);
				} catch (Throwable t) {
					createAdaptiveInstanceError = t;
					throw new IllegalStateException("Failed to create adaptive instance: " + t.toString(), t);
				}
			}
		}
	}

	return (T) instance;
}

private T createAdaptiveExtension() {
	try {
		// 获取Adaptive扩展类字节码,反射获取实例
		return injectExtension((T) getAdaptiveExtensionClass().newInstance());
	} catch (Exception e) {
		throw new IllegalStateException("Can't create adaptive extension " + type + ", cause: " + e.getMessage(), e);
	}
}

private Class<?> getAdaptiveExtensionClass() {
	getExtensionClasses();
	if (cachedAdaptiveClass != null) {
		return cachedAdaptiveClass;
	}
	// Javassist方式或JDK方式创建Adaptive扩展类字节码
	return cachedAdaptiveClass = createAdaptiveExtensionClass();
}

  createAdaptiveExtensionClass源码分析

private Class<?> createAdaptiveExtensionClass() {
	// 创建Adaptive类java代码
	String code = new AdaptiveClassCodeGenerator(type, cachedDefaultName).generate();
	ClassLoader classLoader = findClassLoader();
	org.apache.dubbo.common.compiler.Compiler compiler = ExtensionLoader.getExtensionLoader(org.apache.dubbo.common.compiler.Compiler.class).getAdaptiveExtension();
	// 编译Adaptive类java代码,创建Adaptive类字节码获取Adaptive类Class对象
	return compiler.compile(code, classLoader);
}

  AdaptiveClassCodeGenerator#generate源码分析

public String generate() {
	// no need to generate adaptive class since there's no adaptive method found.
	if (!hasAdaptiveMethod()) {
		throw new IllegalStateException("No adaptive method exist on extension " + type.getName() + ", refuse to create the adaptive class!");
	}

	StringBuilder code = new StringBuilder();
	// package信息
	code.append(generatePackageInfo());
	// import信息
	code.append(generateImports());
	// 类声明信息 public class %s$Adaptive implements %s
	code.append(generateClassDeclaration());

	// 方法信息
	Method[] methods = type.getMethods();
	for (Method method : methods) {
		code.append(generateMethod(method));
	}
	code.append("}");

	if (logger.isDebugEnabled()) {
		logger.debug(code.toString());
	}
	return code.toString();
}

  java代码结果示例

package org.apache.dubbo.common.extension.adaptive;
import org.apache.dubbo.common.extension.ExtensionLoader;
public class HasAdaptiveExt$Adaptive implements org.apache.dubbo.common.extension.adaptive.HasAdaptiveExt {
public java.lang.String echo(org.apache.dubbo.common.URL arg0, java.lang.String arg1)  {
if (arg0 == null) throw new IllegalArgumentException("url == null");
org.apache.dubbo.common.URL url = arg0;
String extName = url.getParameter("has.adaptive.ext", "adaptive");
if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.common.extension.adaptive.HasAdaptiveExt) name from url (" + url.toString() + ") use keys([has.adaptive.ext])");
org.apache.dubbo.common.extension.adaptive.HasAdaptiveExt extension = (org.apache.dubbo.common.extension.adaptive.HasAdaptiveExt)ExtensionLoader.getExtensionLoader(org.apache.dubbo.common.extension.adaptive.HasAdaptiveExt.class).getExtension(extName);
return extension.echo(arg0, arg1);
}
}

Compiler  

  利用Javassist、JDK将java代码编译为Class对象 

  

posted @ 2021-04-25 11:57  BINGJJFLY  阅读(87)  评论(0编辑  收藏  举报