Dubbo源码分析:Dubbo自己实现的IOC

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ZuoAnYinXiang/article/details/82729648

  在创建自适应实例时,都会调用ExtensionLoader的injectExtension方法:

   @SuppressWarnings("unchecked")
    private T createAdaptiveExtension() {
        try {
            /**
             * 传入自适应实例注入到ExtensionLoader
             */
            return injectExtension((T) getAdaptiveExtensionClass().newInstance());
        } catch (Exception e) {
            throw new IllegalStateException("Can not create adaptive extension " + type + ", cause: " + e.getMessage(), e);
        }
    }
private T injectExtension(T instance) {
        try {
            /**
             * 必须要有对象工厂
             */
            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];
                        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) {
                                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;
    }

        dubbo中的IOC实例是通过ExtensionFactory实现的,其实就是检测扩展实现类有没有通过set方法设置的属性,如果有,就通过ExtensionFactory加载而设置。
ExtensionFactory的类实现体系:

    在构造ExtensionLoader对象时,有个对象extensionFactory是必须要创建的,可以看到它就是用自适应实例,而ExtensionFatocry的自适应实例便是AdaptiveExtensionFactory,通过下面它的源码,我们可以发现,它维护了其他非自适应扩展实例,其实也就两个SpiExtensionFactory和SpringExtensionFactory。尝试用这两个实例去加载,加载到便返回。

@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);
    }

    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;
    }

}

       ExtensionFatocry 可以理解为对象工厂,只不过这里的对应就是Dubbo中的扩展Extension,AdaptiveExtensionFactory可以理解为通用扩展实现获取的入口,至于具体的获取方式分为两种,如果一种是通过Dubbo 自己的SPI方式加载到的扩展,同时还支持复用Srping 的方式,可以看看这两种实现的代码便可知:

public class SpiExtensionFactory implements ExtensionFactory {

    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().size() > 0) {
                return loader.getAdaptiveExtension();
            }
        }
        return null;
    }

}

public class SpringExtensionFactory implements ExtensionFactory {
    
    private static final Set<ApplicationContext> contexts = new ConcurrentHashSet<ApplicationContext>();
    
    public static void addApplicationContext(ApplicationContext context) {
        contexts.add(context);
    }

    public static void removeApplicationContext(ApplicationContext context) {
        contexts.remove(context);
    }

    @SuppressWarnings("unchecked")
    public <T> T getExtension(Class<T> type, String name) {
        for (ApplicationContext context : contexts) {
            if (context.containsBean(name)) {
                Object bean = context.getBean(name);
                if (type.isInstance(bean)) {
                    return (T) bean;
                }
            }
        }
        return null;
    }

}

猜你喜欢

转载自blog.csdn.net/ZuoAnYinXiang/article/details/82729648