Dubbo中的IOC,APO源码阅读

384 阅读5分钟
其实我们在SPI源码阅读的时候,已经阅读过Dubbo中的IOC/APO源码部分了,接下来我们再详细的跟踪一下复习一遍。

IOC

ServiceConfig.java

public synchronized void export() {
        // 检测所有的注册中心可用性,并进一步完善<dubbo:service/>的配置
        checkAndUpdateSubConfigs();

        // 若设置的export为false,则不进行服务暴露,直接结束
        if (!shouldExport()) {
            return;
        }
        // 若设置了delay属性,则进行延迟暴露
        if (shouldDelay()) {
            DELAY_EXPORT_EXECUTOR.schedule(this::doExport, getDelay(), TimeUnit.MILLISECONDS);
        } else {
            doExport();
        }
    }


public void checkAndUpdateSubConfigs() {
        // 如果用户没有自定义配置,则使用默认的配置信息
        completeCompoundConfigs();
        // Config Center should always being started first.
        startConfigCenter();
        checkDefault();
        checkProtocol();
        checkApplication();
        // if protocol is not injvm checkRegistry
        // 若不是本地服务暴露,则检测所有注册中心的可用性
        if (!isOnlyInJvm()) {
            checkRegistry();
        }
        this.refresh();
        checkMetadataReport();

        if (StringUtils.isEmpty(interfaceName)) {
            throw new IllegalStateException("<dubbo:service interface=\"\" /> interface not allow null!");
        }

        if (ref instanceof GenericService) {
            interfaceClass = GenericService.class;
            if (StringUtils.isEmpty(generic)) {
                generic = Boolean.TRUE.toString();
            }
        } else {
            try {
                interfaceClass = Class.forName(interfaceName, true, Thread.currentThread()
                        .getContextClassLoader());
            } catch (ClassNotFoundException e) {
                throw new IllegalStateException(e.getMessage(), e);
            }
            checkInterfaceAndMethods(interfaceClass, methods);
            checkRef();
            generic = Boolean.FALSE.toString();
        }
        if (local != null) {
            if ("true".equals(local)) {
                local = interfaceName + "Local";
            }
            Class<?> localClass;
            try {
                localClass = ClassUtils.forNameWithThreadContextClassLoader(local);
            } catch (ClassNotFoundException e) {
                throw new IllegalStateException(e.getMessage(), e);
            }
            if (!interfaceClass.isAssignableFrom(localClass)) {
                throw new IllegalStateException("The local implementation class " + localClass.getName() + " not implement interface " + interfaceName);
            }
        }
        if (stub != null) {
            if ("true".equals(stub)) {
                stub = interfaceName + "Stub";
            }
            Class<?> stubClass;
            try {
                stubClass = ClassUtils.forNameWithThreadContextClassLoader(stub);
            } catch (ClassNotFoundException e) {
                throw new IllegalStateException(e.getMessage(), e);
            }
            if (!interfaceClass.isAssignableFrom(stubClass)) {
                throw new IllegalStateException("The stub implementation class " + stubClass.getName() + " not implement interface " + interfaceName);
            }
        }
        checkStubAndLocal(interfaceClass);
        checkMock(interfaceClass);
    }

AbstractInterfaceConfig.java

protected void checkRegistry() {
    loadRegistriesFromBackwardConfig();

    convertRegistryIdsToRegistries();

    // 遍历所有注册中心,只要有一个不可用,则直接抛出异常
    for (RegistryConfig registryConfig : registries) {
        if (!registryConfig.isValid()) {
            throw new IllegalStateException("No registry config found or it's not a valid config! " +
                    "The registry config is: " + registryConfig);
        }
    }
    // 使用注册中心作为配置中心,如果有必要的话(没有定义配置中心)
    useRegistryForConfigIfNecessary();
}


private void useRegistryForConfigIfNecessary() {
        registries.stream().filter(RegistryConfig::isZookeeperProtocol).findFirst().ifPresent(rc -> {
            // we use the loading status of DynamicConfiguration to decide whether ConfigCenter has been initiated.
            Environment.getInstance().getDynamicConfiguration().orElseGet(() -> {
                ConfigManager configManager = ConfigManager.getInstance();
                ConfigCenterConfig cc = configManager.getConfigCenter().orElse(new ConfigCenterConfig());
                // 使用注册中心初始化配置中心
                cc.setProtocol(rc.getProtocol());
                cc.setAddress(rc.getAddress());
                cc.setHighestPriority(false);
                setConfigCenter(cc);
                // 开启配置中心
                startConfigCenter();
                return null;
            });
        });
    }


void startConfigCenter() {
        if (configCenter == null) {
            ConfigManager.getInstance().getConfigCenter().ifPresent(cc -> this.configCenter = cc);
        }

        if (this.configCenter != null) {
            // TODO there may have duplicate refresh
            this.configCenter.refresh();
            // 从配置中心读取动态配置数据,准备运行环境
            prepareEnvironment();
        }
        ConfigManager.getInstance().refreshAll();
    }


private void prepareEnvironment() {
        if (configCenter.isValid()) {
            if (!configCenter.checkOrUpdateInited()) {
                return;
            }
            // 获取动态配置
            DynamicConfiguration dynamicConfiguration = getDynamicConfiguration(configCenter.toUrl());
            String configContent = dynamicConfiguration.getProperties(configCenter.getConfigFile(), configCenter.getGroup());

            String appGroup = application != null ? application.getName() : null;
            String appConfigContent = null;
            if (StringUtils.isNotEmpty(appGroup)) {
                appConfigContent = dynamicConfiguration.getProperties
                        (StringUtils.isNotEmpty(configCenter.getAppConfigFile()) ? configCenter.getAppConfigFile() : configCenter.getConfigFile(),
                         appGroup
                        );
            }
            try {
                Environment.getInstance().setConfigCenterFirst(configCenter.isHighestPriority());
                Environment.getInstance().updateExternalConfigurationMap(parseProperties(configContent));
                Environment.getInstance().updateAppExternalConfigurationMap(parseProperties(appConfigContent));
            } catch (IOException e) {
                throw new IllegalStateException("Failed to parse configurations from Config Center.", e);
            }
        }
    }


private DynamicConfiguration getDynamicConfiguration(URL url) {
  // 获取动态配置工厂DynamicConfigurationFactory的名称为zookeeper的扩展类实例
  DynamicConfigurationFactory factories = ExtensionLoader
    .getExtensionLoader(DynamicConfigurationFactory.class)
    .getExtension(url.getProtocol());  //
  DynamicConfiguration configuration = factories.getDynamicConfiguration(url);
  Environment.getInstance().setDynamicConfiguration(configuration);
  return configuration;
}

ExtensionLoader.java

// 获取指定名称的扩展类实例
@SuppressWarnings("unchecked")
public T getExtension(String name) {
    if (StringUtils.isEmpty(name)) {
        throw new IllegalArgumentException("Extension name == null");
    }
    if ("true".equals(name)) {
        return getDefaultExtension();
    }
    final Holder<Object> holder = getOrCreateHolder(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) {
        //  getExtensionClasses() 返回当前SPI接口的所有直接扩展类,是个map
        // 其key为扩展名,value为直接扩展类的class
        Class<?> clazz = getExtensionClasses().get(name);
        if (clazz == null) {
            throw findException(name);
        }
        try {
            // 从缓存中获取指定类对应的实例,若为null,则创建一个实例
            T instance = (T) EXTENSION_INSTANCES.get(clazz);
            if (instance == null) {
                EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.newInstance());
                instance = (T) EXTENSION_INSTANCES.get(clazz);
            }
            // 调用instance实例的setter完成注入
            injectExtension(instance);
            // 获取当前SPI接口类型的所有wrapper类
            Set<Class<?>> wrapperClasses = cachedWrapperClasses;
            // 遍历所有wrapper,逐层对instance实例进行包装
            if (CollectionUtils.isNotEmpty(wrapperClasses)) {
                for (Class<?> wrapperClass : wrapperClasses) {
                    instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
                }
            }
            // 返回的是包装过的instance
            return instance;
        } catch (Throwable t) {
            throw new IllegalStateException("Extension instance (name: " + name + ", class: " +
                    type + ") couldn't be instantiated: " + t.getMessage(), t);
        }
    }


private T injectExtension(T instance) {
        try {
            if (objectFactory != null) {
                // 遍历当前instance中的所有方法
                for (Method method : instance.getClass().getMethods()) {
                    // 仅对setter方法进行处理
                    if (isSetter(method)) {
                        /**
                         * Check {@link DisableInject} to see if we need auto injection for this property
                         */
                        // 若一个setter方法上有@DisableInject注解,则不进行注入
                        if (method.getAnnotation(DisableInject.class) != null) {
                            continue;
                        }
                        // 获取当前setter方法的参数类型
                        Class<?> pt = method.getParameterTypes()[0];
                        // 若setter方法的参数类型为基本数据类型,则不进行注入
                        if (ReflectUtils.isPrimitives(pt)) {
                            continue;
                        }
                        try {
                            // 获取setter方法的形参名称
                            String property = getSetterProperty(method);
                            // 获取要注入的实例,即setter的实参
                            Object object = objectFactory.getExtension(pt, property);
                            if (object != null) {
                                // 调用setter完成注入
                                method.invoke(instance, object);
                            }
                        } catch (Exception e) {
                            logger.error("Failed to inject via method " + method.getName()
                                    + " of interface " + type.getName() + ": " + e.getMessage(), e);
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return instance;
    }

image-20210101095402403

image-20210101100025871

public <T> T getExtension(Class<T> type, String name) {
    // 若当前type为SPI接口
    if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
        ExtensionLoader<T> loader = ExtensionLoader.getExtensionLoader(type);
        // 若当前type的直接扩展类不空,则返回其adaptive实例
        if (!loader.getSupportedExtensions().isEmpty()) {
            return loader.getAdaptiveExtension();
        }
    }
    return null;
}

ExtensionLoader.java

public <T> T getExtension(Class<T> type, String name) {
    // 若当前type为SPI接口
    if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
        ExtensionLoader<T> loader = ExtensionLoader.getExtensionLoader(type);
        // 若当前type的直接扩展类不空,则返回其adaptive实例
        if (!loader.getSupportedExtensions().isEmpty()) {
            return loader.getAdaptiveExtension();
        }
    }
    return null;
}

image-20210101095800829

public <T> T getExtension(Class<T> type, String name) {

    //SPI should be get from SpiExtensionFactory
    // 若当前type为SPI接口,则直接结束,因为Spring方式不处理SPI接口实例的创建
    if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
        return null;
    }

    // 遍历所有Spring容器,根据名称从中查找实例
    for (ApplicationContext context : CONTEXTS) {
        if (context.containsBean(name)) {
            Object bean = context.getBean(name);
            if (type.isInstance(bean)) {
                return (T) bean;
            }
        }
    }

    logger.warn("No spring extension (bean) named:" + name + ", try to find an extension (bean) of type " + type.getName());

    // 这个type不能是Object
    if (Object.class == type) {
        return null;
    }

    // 遍历所有Spring容器,根据类型从中查找实例
    for (ApplicationContext context : CONTEXTS) {
        try {
            return context.getBean(type);
        } catch (NoUniqueBeanDefinitionException multiBeanExe) {
            logger.warn("Find more than 1 spring extensions (beans) of type " + type.getName() + ", will stop auto injection. Please make sure you have specified the concrete parameter type and there's only one extension of that type.");
        } catch (NoSuchBeanDefinitionException noBeanExe) {
            if (logger.isDebugEnabled()) {
                logger.debug("Error when get spring extension(bean) for type:" + type.getName(), noBeanExe);
            }
        }
    }

    logger.warn("No spring extension (bean) named:" + name + ", type:" + type.getName() + " found, stop get bean.");

    return null;
}

AOP

​ Dubbo 的 AOP 是对 SPI 扩展类进行增强的方式,而 Wrapper 机制就是对 SPI 扩展类的增强。不同 SPI 的不同 Wrapper,其增强的功能不同。这里引用一下我们之前在学习Dubbo中的四大扩展机制中的Wraper示例。它会生成一个Adaptive扩展类,它的格式是这样的。

package <SPI 接口所在包>;
public class SPI 接口名$Adpative implements SPI 接口 {
     public adaptiveMethod (arg0, arg1, ...) {
             // 注意,下面的判断仅对 URL 类型,或可以获取到 URL 类型值的参数进行判断
             // 例如,dubbo 的 Invoker 类型中就包含有 URL 属性
            if(arg1==null) 
                throw new IllegalArgumentException(异常信息);
            if(arg1.getUrl()==null) 
                throw new IllegalArgumentException(异常信息);

             URL url = arg1.getUrl();

            // 其会根据@Adaptive 注解上声明的 Key 的顺序,从 URL 获取 Value,
            // 作为实际扩展类。若有默认扩展类,则获取默认扩展类名;否则获取
            // 指定扩展名名。
             String extName = url.get 接口名() == null?默认扩展前辍名:url.get 接口名();
             if(extName==null) throw new IllegalStateException(异常信息);
             SPI 接口 extension = ExtensionLoader.getExtensionLoader(SPI 接口.class)
            .getExtension(extName);
         	return extension. adaptiveMethod(arg0, arg1, ...);
         }
    
         public unAdaptiveMethod( arg0, arg1, ...) {
         	throw new UnsupportedOperationException(异常信息);
     	} 
}		

它会调用getExtensionLoader()创建并执行这个类,然后再去调用被包装的真正的业务方法。从而达到AOP思想的增强。