Dubbo中SPI的原理

為{幸葍}努か 提交于 2019-12-26 16:07:53

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

dubbo中SPI机制,主要围绕三个注解:@SPI、@Adaptive、Activate

  • @SPI:作用域为接口。它表示该类实现了SPI。
  • @Adaptive:作用域为方法,类。如果在类型定义则表明该类为自适应类,不需要额外动态生成。如果用在方法上,则会单独动态生成自适应类。
  • @Activate:通常作用域为类。用于多个扩展的配置。

三种常用的用法

// 这一种是最简单的,直接得到扩展实例
Exchanger exchanger = ExtensionLoader.getExtensionLoader(Exchanger.class).getExtension(type);
	public T getExtension(String name) {
		if (name == null || name.length() == 0)
			throw new IllegalArgumentException("Extension name == null");
		if ("true".equals(name)) {
			return getDefaultExtension();
		}
		// 从缓存中读取
		Holder<Object> holder = cachedInstances.get(name);
		if (holder == null) {
			cachedInstances.putIfAbsent(name, new Holder<Object>());
			holder = cachedInstances.get(name);
		}
		Object instance = holder.get();
		if (instance == null) {// 为空者构造,并放入缓存
			synchronized (holder) {
				instance = holder.get();
				if (instance == null) {
					// 创建扩展实例
					instance = createExtension(name);
					holder.set(instance);
				}
			}
		}
		return (T) instance;
	}

	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) {
				EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.newInstance());
				instance = (T) EXTENSION_INSTANCES.get(clazz);
			}
			injectExtension(instance);
			Set<Class<?>> wrapperClasses = cachedWrapperClasses;
			if (wrapperClasses != null && !wrapperClasses.isEmpty()) {
				for (Class<?> wrapperClass : wrapperClasses) {
					// wrapperClass.getConstructor(type).newInstance(instance)包装wrapper。
					// 如:ProtocolFilterWrapper、ProtocolListenerWrapper等
					instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
				}
			}
			return instance;
		} catch (Throwable t) {
			throw new IllegalStateException("Extension instance(name: " + name + ", class: " + type
					+ ")  could not be instantiated: " + t.getMessage(), t);
		}
	}
// 这种会有个中间类Adpative自适应中间类。然后在Adpdative类中,再调用getExtension(String name)
Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
	/**
	 * 得到Adaptive扩展
	 * 
	 * 如果实现类上没有@Adaptive注解,该类型会动态生成:Xxx$Adaptive类
	 * 如果有配置@Adaptive注解,直接用改类作为自适应类
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public T getAdaptiveExtension() {
		Object instance = cachedAdaptiveInstance.get();
		if (instance == null) {
			if (createAdaptiveInstanceError == null) {
				synchronized (cachedAdaptiveInstance) {
					instance = cachedAdaptiveInstance.get();
					if (instance == null) {
						try {
							// 创建自适应扩展
							instance = createAdaptiveExtension();
							cachedAdaptiveInstance.set(instance);
						} catch (Throwable t) {
							createAdaptiveInstanceError = t;
							throw new IllegalStateException("fail to create adaptive instance: " + t.toString(), t);
						}
					}
				}
			} else {
				throw new IllegalStateException(
						"fail to create adaptive instance: " + createAdaptiveInstanceError.toString(),
						createAdaptiveInstanceError);
			}
		}

		return (T) instance;
	}

	private T createAdaptiveExtension() {
		try {
			return injectExtension((T) getAdaptiveExtensionClass().newInstance());
		} catch (Exception e) {
			throw new IllegalStateException("Can not create adaptive extension " + type + ", cause: " + e.getMessage(),
					e);
		}
	}

	private Class<?> getAdaptiveExtensionClass() {
		getExtensionClasses();// 加载扩展类
		if (cachedAdaptiveClass != null) {// 如果类上加了@Adaptive就已该类作为自适应类。否者,动态生成自适应类
			return cachedAdaptiveClass;
		}
		return cachedAdaptiveClass = createAdaptiveExtensionClass();
	}

	private Class<?> createAdaptiveExtensionClass() {
		// 生成Classjava代码
		String code = createAdaptiveExtensionClassCode();
		ClassLoader classLoader = findClassLoader();
		com.alibaba.dubbo.common.compiler.Compiler compiler = ExtensionLoader
				.getExtensionLoader(com.alibaba.dubbo.common.compiler.Compiler.class).getAdaptiveExtension();
		return compiler.compile(code, classLoader);
	}

List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.getUrl(), key, group)
	public List<T> getActivateExtension(URL url, String[] values, String group) {
		List<T> exts = new ArrayList<T>();
		List<String> names = values == null ? new ArrayList<String>(0) : Arrays.asList(values);
		if (!names.contains(Constants.REMOVE_VALUE_PREFIX + Constants.DEFAULT_KEY)) {// names没有包含“-default”
			getExtensionClasses();// 加载所有的扩展类
			for (Map.Entry<String, Activate> entry : cachedActivates.entrySet()) {
				String name = entry.getKey();
				Activate activate = entry.getValue();
				if (isMatchGroup(group, activate.group())) {// 判断分组是否匹配
					T ext = getExtension(name);
					if (!names.contains(name) && !names.contains(Constants.REMOVE_VALUE_PREFIX + name)
							&& isActive(activate, url)) {
						exts.add(ext);
					}
				}
			}
			Collections.sort(exts, ActivateComparator.COMPARATOR);
		}
		List<T> usrs = new ArrayList<T>();
		for (int i = 0; i < names.size(); i++) {
			String name = names.get(i);
			if (!name.startsWith(Constants.REMOVE_VALUE_PREFIX)
					&& !names.contains(Constants.REMOVE_VALUE_PREFIX + name)) {
				if (Constants.DEFAULT_KEY.equals(name)) {
					if (!usrs.isEmpty()) {
						exts.addAll(0, usrs);
						usrs.clear();
					}
				} else {
					T ext = getExtension(name);
					usrs.add(ext);
				}
			}
		}
		// 合并activate扩展和url配置扩展
		if (!usrs.isEmpty()) {
			exts.addAll(usrs);
		}
		return exts;
	}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!