4Dubbo的SPI机制分析3Dubbo的IOC依赖注入

2次阅读

共计 5622 个字符,预计需要花费 15 分钟才能阅读完成。

1、Dubbo 的 IOC 例子

 @Test
public void test1(){ExtensionLoader<AdaptiveExt> loader = ExtensionLoader.getExtensionLoader(AdaptiveExt.class);
    AdaptiveExt adaptiveExtension = loader.getExtension("dubbo");
    URL url = URL.valueOf("test://localhost/test");
    adaptiveExtension.echo("d", url);
}

public class DubboAdaptiveExt implements AdaptiveExt {

    // dubbo 中有依赖 AdaptiveExt 类型的变量
    private AdaptiveExt adaptiveExt;

    public void setAdaptiveExt(AdaptiveExt adaptiveExt) {this.adaptiveExt = adaptiveExt;}

    @Override
    public String echo(String msg, URL url) {System.out.println(this.adaptiveExt.echo(msg, url));
        return "dubbo";
    }
}
// 此时 ThriftAdaptiveExt 上面是标注了 @Adaptive 注解的
@Adaptive
public class ThriftAdaptiveExt implements AdaptiveExt {
    @Override
    public String echo(String msg, URL url) {return "thrift";}
}

2、Dubbo 的 IOC 需要用到的 ExtensionFactory

Spring 的 IOC 中, 给生成的 bean 注入依赖, 是调用 context.getBean(name) 去获得要注入的 bean.Dubbo 的 IOC 类似, 它通过 ExtensionFactory 类型的变量 objectFactory 去 dubbo 中获取 bean, 核心代码 objectFactory.getExtension(pt, property). 下面先分析一下 objectFactory 的创建过程.objectFactory 需要用到 SpringExtensionFactory 和 SpiExtensionFactory. 先看一下 ExtenionFactory 的实现类, 如下图. 下面通过源码分析 objectFactory 的生成过程.

这里的 getExtensionLoader() 详细分析可以参见: Dubbo 的 SPI 机制 1 -SPI 简单分析

ExtensionLoader<AdaptiveExt> loader = ExtensionLoader.getExtensionLoader(AdaptiveExt.class);

public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> 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;
}

 private ExtensionLoader(Class<?> type) {
    this.type = type;
    // 这里的 type 是 AdaptiveExt.class, 所以会执行后面的代码, 加载并创建 SpiExtensionFactory
    // 和 SpringExtensionFactory
    objectFactory = (type == ExtensionFactory.class ? null : 
                   ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
}
public T getAdaptiveExtension() {Object instance = cachedAdaptiveInstance.get();
    if (instance == null) {if (createAdaptiveInstanceError == null) {synchronized (cachedAdaptiveInstance) {instance = cachedAdaptiveInstance.get();
                if (instance == null) {
                    try {
                        // 创建自适应拓展代理类对象并放入缓存, 这里创建的就是 ExtensionFactory 的自适应拓展对象
                        instance = createAdaptiveExtension();
                        cachedAdaptiveInstance.set(instance);
                    } catch (Throwable t) {// 抛异常}
                }
            }
        }
    }
    return (T) instance;
}
 private T createAdaptiveExtension() {
    try {
        // 分为 3 步:1 是创建自适应拓展代理类 Class 对象,2 是通过反射创建对象,3 是给创建的对象按需依赖注入
        return injectExtension((T) getAdaptiveExtensionClass().newInstance());
    } catch (Exception e) {// 抛异常}
}

getExtensionClasses() 方法详细分析可以参见: Dubbo 的 SPI 机制 1 -SPI 简单分析

private Class<?> getAdaptiveExtensionClass() {
    // 这里前面文章已经分析过了, 它会去加载默认目录下的 ExtensionFactory 的实现类, 总共有 3 个, 目录是
    // META-INF/dubbo/internal/, 该目录对应两个文件, 文件内容见下, 由于 AdaptiveExtensionFactory 上面
    // 标注了 @Adaptive 注解, 所以它优先级最高, 它就是 ExtensionFactory 的默认实现类
    getExtensionClasses();
    // 如果有标注了 @Adaptive 注解实现类, 那么 cachedAdaptiveClass 不为空, 直接返回
    if (cachedAdaptiveClass != null) {
        // 这里直接返回,cachedAdaptiveClass = AdaptiveExtensionFactory.class
        return cachedAdaptiveClass;
    }
    // 不会再走这一步
    return cachedAdaptiveClass = createAdaptiveExtensionClass();}
 文件 1 内容:
// 其中 AdaptiveExtensionFactory 上面标注了 @Adaptive 注解
adaptive=com.alibaba.dubbo.common.extension.factory.AdaptiveExtensionFactory
spi=com.alibaba.dubbo.common.extension.factory.SpiExtensionFactory

文件 2 内容:
spring=com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory
@Adaptive
public class AdaptiveExtensionFactory implements ExtensionFactory {
// 分析完了 getAdaptiveExtensionClass(), 它是返回 AdaptiveExtensionFactory, 接下来 newInstance 会
// 调用它默认的构造方法
return injectExtension((T) getAdaptiveExtensionClass().newInstance());

@Adaptive
public class AdaptiveExtensionFactory implements ExtensionFactory {
    // 里面维护 SpringExtensionFactory 和 SpiExtensionFactory
    private final List<ExtensionFactory> factories;

    public AdaptiveExtensionFactory() {
        ExtensionLoader<ExtensionFactory> loader = 
                                    ExtensionLoader.getExtensionLoader(ExtensionFactory.class);
        List<ExtensionFactory> list = new ArrayList<ExtensionFactory>();
        for (String name : loader.getSupportedExtensions()) {
            // 分别给 SpringExtensionFactory 和 SpiExtensionFactory 创建对象并放入 list 中
            list.add(loader.getExtension(name));
        }
        factories = Collections.unmodifiableList(list);
    }
}

3、Dubbo 的 IOC 源码分析

// 上面已经分析过了第一行代码, 这里面会创建 ExtensionFactory 类型的变量 objectFactory, 这里面维护了一个 list,
// list 里面有 SpringExtensionFactory 和 SpiExtensionFactory 类型的实例,Dubbo 的 IOC 获取 bean 就是通过这两个
// 变量去获取的
ExtensionLoader<AdaptiveExt> loader = ExtensionLoader.getExtensionLoader(AdaptiveExt.class);
AdaptiveExt adaptiveExtension = loader.getExtension("dubbo");

public T getExtension(String name) {
    // 删去一些代码
    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) {
    // 从配置文件中加载所有的拓展类, 可得到“配置项名称”到“配置类”的映射关系表
    // 这里我们指定了名字 dubbo, 并不是通过 getAdaptiveExtension 方法去获得自适应拓展类, 这点要区分
    // 所以这里拿到的是 com.alibaba.dubbo.demo.provider.adaptive.impl.DubboAdaptiveExt
    Class<?> clazz = getExtensionClasses().get(name);
    if (clazz == null) {throw findException(name);
    }
    try {
        // 也是尝试先从缓存获取, 获取不到通过反射创建一个并放到缓存中
        T instance = (T) EXTENSION_INSTANCES.get(clazz);
        if (instance == null) {
            // 这里直接通过反射创建 DubboAdaptiveExt 的实例, 然后给他依赖注入
            EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.newInstance());
            instance = (T) EXTENSION_INSTANCES.get(clazz);
        }
        
        // 依赖注入
        injectExtension(instance);
        
        return instance;
    } 
}
private T injectExtension(T instance) {if (objectFactory != null) {for (Method method : instance.getClass().getMethods()) {if (method.getName().startsWith("set")
            && method.getParameterTypes().length == 1
            && Modifier.isPublic(method.getModifiers())) {Class<?> pt = method.getParameterTypes()[0];
            
            String property = 
               method.getName().length() > 3 ? 
                  method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4) : "";
            Object object = objectFactory.getExtension(pt, property);
            if (object != null) {method.invoke(instance, object);
            }
         }   
    }
 }
 return instance;
}

正文完
 0