Dubbo IOC

在Dubbo中, 无论是通过name 获取指定扩展类, 还是自适应扩展,都会在加载完扩展,进行一次依赖注入,我们可以把这个称为Dubbo的IOC机制。
例如:

private T createExtension(String name) {
    // throws any possible exception in loading period.
    findException(name);
    Class<?> clazz = getExtensionClasses().get(name);
    if (clazz == null) {
        throw noExtensionException(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;
        // 这里会循环注入 Wrapper类最后返回的instance 是多个wrapper包裹之后的instance
        if (CollectionUtils.isNotEmpty(wrapperClasses)) {
            for (Class<?> wrapperClass : wrapperClasses) {
                // 注意这里 IOC操作
                instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
            }
        }
        return instance;
    } catch (Throwable t) {
        throw new IllegalStateException("Extension instance (name: " + name + ", class: " +
                type + ") couldn't be instantiated: " + t.getMessage(), t);
    }
}

T) wrapperClass.getConstructor(type).newInstance(instance)
是利用反射进行实例化。他的最外层injectExtension方法,所做的就是Dubbo的IOC,将扩展中的属性进行赋值。接下来我们看一下他的实现

private T injectExtension(T instance) {
    try {
        if (objectFactory != null) {
            // 便利所有方法
            for (Method method : instance.getClass().getMethods()) {
                // 寻找set方法
                if (method.getName().startsWith("set")
                        && method.getParameterTypes().length == 1
                        && Modifier.isPublic(method.getModifiers())) {
            
                    Class<?> pt = method.getParameterTypes()[0];
                    try {
                        // 获取属性名称
                        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) {
                            // 执行setter方法,完成 IOC操作
                            method.invoke(instance, object);
                        }
                    } catch (Exception e) {
                        logger.error("fail to inject via method " + method.getName()
                                + " of interface " + type.getName() + ": " + e.getMessage(), e);
                    }
                }
            }
        }
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
    }
    return instance;
}

遍历出类中所有的方法,寻找其中的set方法,根据方法命名获取到需要从容器内搜索的对象的名称,如果能搜索到,就利用反射进行注入。逻辑很清晰,唯一的疑惑点就是,根据名称和类型搜索相应的对象的逻辑,也就是 Object object = objectFactory.getExtension(pt, property)
objectFactory是怎么来的呢?

private final ExtensionFactory objectFactory; 这是一个final变量,不可变,那我们去看他的构造方法去

private ExtensionLoader(Class<?> type) {
    this.type = type;
    objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
}

很明显这是在我们在开头 通过接口的class 获取 ExtentionLoader的时候,创建的
ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension()); 获取到的是 AdaptiveExtensionFactory的实例,因为他的类上带有 @Adaptive注解.

@Adaptive
public class AdaptiveExtensionFactory implements ExtensionFactory {

    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()) {
            list.add(loader.getExtension(name));
        }
        factories = Collections.unmodifiableList(list);
    }

    @Override
    public <T> T getExtension(Class<T> type, String name) {
        for (ExtensionFactory factory : factories) {
            T extension = factory.getExtension(type, name);
            if (extension != null) {
                return extension;
            }
        }
        return null;
    }

}

所以最后就是它作为扩展类,也就是objectFactory的实例对象。所以当调用objectFactory.getExtension 实际执行的是AdaptiveExtensionFactory的 getExtension方法.
我们可以看到他是从factories 里去拿, factories是构造函数中初始化的.

list.add(loader.getExtension(name));
那么我们在common子工程下,找到如下的SPI扩展文件 META-INF/dubbo/internal/org.apache.dubbo.common.extension.ExtensionFactory

adaptive=org.apache.dubbo.common.extension.factory.AdaptiveExtensionFactory
spi=org.apache.dubbo.common.extension.factory.SpiExtensionFactory

ExtensionFactory类型的扩展,出了ExtensionFactory有两个,一个 SpiExtensionFactory,另外一个是SpringExtensionFactory

SpiExtensionFactory 如何去搜索扩展呢? 我们去看代码。

/**
 * SpiExtensionFactory
 */
public class SpiExtensionFactory implements ExtensionFactory {

    @Override
    public <T> T getExtension(Class<T> type, String name) {
        if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
            ExtensionLoader<T> loader = ExtensionLoader.getExtensionLoader(type);
            if (!loader.getSupportedExtensions().isEmpty()) {
                return loader.getAdaptiveExtension();
            }
        }
        return null;
    }

}

type是 接口,且带有 @SPI注解的,获取Adaptive扩展。

原创文章 132 获赞 23 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_33797928/article/details/102773732
ioc