extensionLoader = ExtensionLoader.getExtensionLoader(UserService.class);//loader userServiceImpl1UserService userServiceImpl1 = extensionLoader.getExtension("userServiceImpl1");userServiceImpl1.findById(1);//loader userServiceImpl2UserService userServiceImpl2 = extensionLoader.getExtension("userServiceImpl2");userServiceImpl2.findById(2);}}结果输出
UserServiceImpl1 find User 1UserServiceImpl2 find User 2
Dubbo SPI 源码解析首先我们先来介绍一下 ExtensionLoader 。 ExtensionLoader 在它的作用主要有几个:自动注入扩展依赖;封装扩展在扩展类中;默认的扩展是一个包装的适配器 。
下面是它的相关属性代码
//全局变量 key:value=http://kandian.youth.cn/index/类:扩展private static final ConcurrentMap, ExtensionLoader>> EXTENSION_LOADERS = new ConcurrentHashMap<>(64);//全局变量 key:value=http://kandian.youth.cn/index/类:实例private static final ConcurrentMap, Object> EXTENSION_INSTANCES = new ConcurrentHashMap<>(64);//所属 Class 的类型private final Class> type;//加载扩展类的工厂private final ExtensionFactory objectFactory;//全局变量 key:value=http://kandian.youth.cn/index/类:实例别名private final ConcurrentMap, String> cachedNames = new ConcurrentHashMap<>();//全局变量 key:value=http://kandian.youth.cn/index/实例别名:类private final Holder
我们从 dmeo 中的 ExtensionLoader.getExtensionLoader 开始入手 。
public staticExtensionLoader getExtensionLoader(Class type) {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 Exception}//根据 类 去获取ExtensionLoader loader = (ExtensionLoader) EXTENSION_LOADERS.get(type);//如果等于 null 就新建一个if (loader == null) {EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader(type));loader = (ExtensionLoader) EXTENSION_LOADERS.get(type);}return loader;}
上面代码还是比较简单 , 可以看出只是为了为类创建一个 Holder 。 但是实际上 , 在 new ExtensionLoader() 的时候 , 还会有一些操作 , 这个下面会讲 。 上面生成了 Holder 后就会返回 。 然后调用 ExtensionLoader.getExtension() 。
//通过名称获取扩展public T getExtension(String name, boolean wrap) {if (StringUtils.isEmpty(name)) {throw new IllegalArgumentException("Extension name == null");}//如果为 true 就返回默认对象if ("true".equals(name)) {return getDefaultExtension();}//获取 holderfinal Holder
下面是创建实例的代码
private T createExtension(String name, boolean wrap) {//从配置文件中加载所有的拓展类 , 可得到“配置项名称”到“配置类”的映射关系表Class> clazz = getExtensionClasses().get(name);if (clazz == null) {throw findException(name);}try {//EXTENSION_INSTANCES 是一个 Map , 是 Class:实例 的映射表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> wrapperClassesList = new ArrayList<>();if (cachedWrapperClasses != null) {wrapperClassesList.addAll(cachedWrapperClasses);wrapperClassesList.sort(WrapperComparator.COMPARATOR);Collections.reverse(wrapperClassesList);}//循环创建 Wrapperif (CollectionUtils.isNotEmpty(wrapperClassesList)) {for (Class> wrapperClass : wrapperClassesList) {//通过注解获取Wrapper wrapper = wrapperClass.getAnnotation(Wrapper.class);//进行匹配//讲实例作为参数传进 Wrapper 构造方法 , 并通过反射得到实例//然后往 Wrapper 进行依赖注入 , 然后再 Wrapper 再次赋值给 instance 变量if (wrapper == null|| (ArrayUtils.contains(wrapper.matches(), name)}}}}//若该对象实现了org.apache.dubbo.common.context.Lifecycle//则调用它的initialize()方法完成初始化initExtension(instance);return instance;} catch (Throwable t) {//...}}