Dubbo -ExtensionLoader-源码-解析

33 篇文章 0 订阅

ExtensionLoader

  • getExtensionLoader 获取扩展点加载器 并加载所对应的所有的扩展点实现
  • getExtension 根据name 获取扩展的指定实现
成员变量

    private static final Logger logger = LoggerFactory.getLogger(ExtensionLoader.class);

    private static final Pattern NAME_SEPARATOR = Pattern.compile("\\s*[,]+\\s*");
    /**
     * 一个扩展接口对应一个 ExtensionLoader 实例,
     * 该集合缓存了全部 ExtensionLoader 实例,
     * 其中的 Key 为扩展接口,Value 为加载其扩展实现的 ExtensionLoader 实例。
     */
    private static final ConcurrentMap<Class<?>, ExtensionLoader<?>> EXTENSION_LOADERS = new ConcurrentHashMap<>(64);
    /**
     * 该集合缓存了扩展实现类与其实例对象的映射关系。在前文示例中,Key 为 Class,Value 为 DubboProtocol 对象。
     */
    private static final ConcurrentMap<Class<?>, Object> EXTENSION_INSTANCES = new ConcurrentHashMap<>(64);
    /**
     前 ExtensionLoader 实例负责加载扩展接口。
     */
    private final Class<?> type;

    private final ExtensionFactory objectFactory;
    /**
     *
     * 缓存了该 ExtensionLoader 加载的扩展实现类与扩展名之间的映射关系。
     */
    private final ConcurrentMap<Class<?>, String> cachedNames = new ConcurrentHashMap<>();
    /**
     * 缓存了该 ExtensionLoader 加载的扩展名与扩展实现类之间的映射关系。cachedNames 集合的反向关系缓存
     */
    private final Holder<Map<String, Class<?>>> cachedClasses = new Holder<>();

    private final Map<String, Object> cachedActivates = new ConcurrentHashMap<>();
    /**
     * 缓存了该 ExtensionLoader 加载的扩展名与扩展实现对象之间的映射关系。
     */
    private final ConcurrentMap<String, Holder<Object>> cachedInstances = new ConcurrentHashMap<>();
    private final Holder<Object> cachedAdaptiveInstance = new Holder<>();
    private volatile Class<?> cachedAdaptiveClass = null;
    /**
     * 记录了 type 这个扩展接口上 @SPI 注解的 value 值,也就是默认扩展名。
     */
    private String cachedDefaultName;
    private volatile Throwable createAdaptiveInstanceError;

    private Set<Class<?>> cachedWrapperClasses;

    private Map<String, IllegalStateException> exceptions = new ConcurrentHashMap<>();

    private static volatile LoadingStrategy[] strategies = loadLoadingStrategies();
构造方法

    private ExtensionLoader(Class<?> type) {
        this.type = type;
        //创建ExtensionFactory ,SPI加载ExtensionFactory也是扩展点
        objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
    }
	//判断方法
    private static <T> boolean withExtensionAnnotation(Class<T> type) {
       //包含`@SPI`注解在接口上
        return type.isAnnotationPresent(SPI.class);
    }
getExtensionLoader

    /**
     * 根据扩展接口从 EXTENSION_LOADERS 缓存中查找相应的 ExtensionLoader 实例
     */
    @SuppressWarnings("unchecked")
    public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
        //判断是否为NULL
        if (type == null) {
            throw new IllegalArgumentException("Extension type == null");
        }
        //不是接口就报错
        if (!type.isInterface()) {
            throw new IllegalArgumentException("Extension type (" + type + ") is not an interface!");
        }
        //判断 是否有扩展注解SPI,没有就报错  type.isAnnotationPresent(SPI.class);
        if (!withExtensionAnnotation(type)) {
            throw new IllegalArgumentException("Extension type (" + type +
                    ") is not an extension, because it is NOT annotated with @" + SPI.class.getSimpleName() + "!");
        }
        /**
         * 从缓存集合中获取对应的接口的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);
        }
        //返回ExtensionLoader
        return loader;
    }
getExtension
 /**
     * Find the extension with the given name. If the specified name is not found, then {@link IllegalStateException}
     * will be thrown.
     * 得到接口对应的 ExtensionLoader 对象之后会调用其 getExtension() 方法,根据传入的扩展名称从 cachedInstances 缓存中查找扩展实现的实例
     */
    @SuppressWarnings("unchecked")
    public T getExtension(String name) {
        if (StringUtils.isEmpty(name)) {
            //名称为空
            throw new IllegalArgumentException("Extension name == null");
        }
        if ("true".equals(name)) {
            //加载默认的扩展实现 如果name=true
            return getDefaultExtension();
        }
        //getOrCreateHolder()方法中封装了查找cachedInstances缓存的逻辑
        final Holder<Object> holder = getOrCreateHolder(name);
        Object instance = holder.get();
        //double-check防止并发问题
        if (instance == null) {
            synchronized (holder) {
                instance = holder.get();
                if (instance == null) {
                    //根据扩展名从SPI配置文件中查找对应的扩展实现类
                    instance = createExtension(name);
                    holder.set(instance);
                }
            }
        }
        return (T) instance;
    }


getOrDefaultExtension
public T getOrDefaultExtension(String name) {
        //获取默认
        return containsExtension(name) ? getExtension(name) : getDefaultExtension();
    }

    /**
     *获取默认的扩展类
     */
    public T getDefaultExtension() {
        //获取扩展类
        getExtensionClasses();
        if (StringUtils.isBlank(cachedDefaultName) || "true".equals(cachedDefaultName)) {
            return null;
        }
        return getExtension(cachedDefaultName);
    }

//判断是否存在
    public boolean hasExtension(String name) {
        if (StringUtils.isEmpty(name)) {
            throw new IllegalArgumentException("Extension name == null");
        }
        //根据名称获取扩展类
        Class<?> c = this.getExtensionClass(name);
        return c != null;
    }

getExtensionClasses

    private Map<String, Class<?>> getExtensionClasses() {
        //从缓存中获取 ExtensionLoader 加载的扩展名与扩展实现类之间的映射关系。cachedNames 集合的反向关系缓存
        Map<String, Class<?>> classes = cachedClasses.get();
        if (classes == null) {
            synchronized (cachedClasses) {
                classes = cachedClasses.get();
                if (classes == null) {
                    //加载配置文件
                    classes = loadExtensionClasses();
                    cachedClasses.set(classes);
                }
            }
        }
        return classes;
    }
构造中获取
objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());



/**
 * ExtensionFactory
 * 根据 传入的扩展点类型,名称 获取扩展实现 与SPI中的名称挂钩
 * adaptive=org.apache.dubbo.common.extension.factory.AdaptiveExtensionFactory
 * spi=org.apache.dubbo.common.extension.factory.SpiExtensionFactory
 * dubbo-common/src/main/resources/METAINF/dubbo/internal/org.apache.dubbo.common.extension.ExtensionFactory 中看到,他默认实现
 */
@SPI
public interface ExtensionFactory {

    /**
     * Get extension.
     *
     * @param type object type.
     * @param name object name.
     * @return object instance.
     */
    <T> T getExtension(Class<T> type, String name);

}

getAdaptiveExtension
    public T getAdaptiveExtension() {
        //从缓存中获取
        Object instance = cachedAdaptiveInstance.get();
        if (instance == null) {
            //为空判断有没有错误
            if (createAdaptiveInstanceError != null) {
                throw new IllegalStateException("Failed to create adaptive instance: " +
                        createAdaptiveInstanceError.toString(),
                        createAdaptiveInstanceError);
            }
            //加锁
            synchronized (cachedAdaptiveInstance) {
                //再次从缓存中获取
                instance = cachedAdaptiveInstance.get();
                if (instance == null) {
                    try {
                        //创建AdaptiveExtension
                        instance = createAdaptiveExtension();
                        //放入缓存
                        cachedAdaptiveInstance.set(instance);
                    } catch (Throwable t) {
                        createAdaptiveInstanceError = t;
                        throw new IllegalStateException("Failed to create adaptive instance: " + t.toString(), t);
                    }
                }
            }
        }

        return (T) instance;
    }

AdaptiveExtensionFactory

在这里插入图片描述

  • SpiExtensionFactory

public class SpiExtensionFactory implements ExtensionFactory {

    @Override
    public <T> T getExtension(Class<T> type, String name) {
        //判断是否为接口,是否有SPI注解
        if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
            // 查找type对应的ExtensionLoader实例
            ExtensionLoader<T> loader = ExtensionLoader.getExtensionLoader(type);
            if (!loader.getSupportedExtensions().isEmpty()) {
                //获取适配器实现
                return loader.getAdaptiveExtension();
            }
        }
        return null;
    }

}
  • SpringExtensionFactory
    @Override
    @SuppressWarnings("unchecked")
    public <T> T getExtension(Class<T> type, String name) {

        //SPI should be get from SpiExtensionFactory
        if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
            //如果是接口,并且有SPI注解,就使用SpiExtensionFactory获取
            return null;
        }

        for (ApplicationContext context : CONTEXTS) {
            //从Spring BeanFactory中获取对应的Bean实现
            T bean = BeanFactoryUtils.getOptionalBean(context, name, type);
            if (bean != null) {
                return bean;
            }
        }

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

        return null;
    }
  • AdaptiveExtensionFactory 这个类加了Adaptive注解

@Adaptive
public class AdaptiveExtensionFactory implements ExtensionFactory {

    private final List<ExtensionFactory> factories;

    public AdaptiveExtensionFactory() {
        //获取针对ExtensionFactory扩展加载器 org.apache.dubbo.common.extension.factory.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;
    }

}

在这里插入图片描述

  • 获取所有支持
  //得到支持的扩展
    public Set<String> getSupportedExtensions() {
        Map<String, Class<?>> clazzes = getExtensionClasses();
          //获取扩展点的名称
        return Collections.unmodifiableSet(new TreeSet<>(clazzes.keySet()));
    }

在这里插入图片描述

getExtensionClasses

    private Map<String, Class<?>> getExtensionClasses() {
        //从缓存中获取 ExtensionLoader 加载的扩展名与扩展实现类之间的映射关系。cachedNames 集合的反向关系缓存
        Map<String, Class<?>> classes = cachedClasses.get();
        if (classes == null) {
            synchronized (cachedClasses) {
                classes = cachedClasses.get();
                if (classes == null) {
                    //加载配置文件
                    classes = loadExtensionClasses();
                    cachedClasses.set(classes);
                }
            }
        }
        return classes;
    }

loadExtensionClasses

    /**
     * synchronized in getExtensionClasses 同步加载
     */
    private Map<String, Class<?>> loadExtensionClasses() {
        //获取默认的扩展实现名称
        cacheDefaultExtensionName();
        //创建一个窗口
        Map<String, Class<?>> extensionClasses = new HashMap<>();
        /**
         * META-INF/dubbo/
         * META-INF/dubbo/internal/
         * META-INF/services/
         * 根据不同的加载策略去不同的文件夹下加载扩展
         */
        for (LoadingStrategy strategy : strategies) {
            loadDirectory(extensionClasses, strategy.directory(), type.getName(), strategy.preferExtensionClassLoader(), strategy.overridden(), strategy.excludedPackages());
            loadDirectory(extensionClasses, strategy.directory(), type.getName().replace("org.apache", "com.alibaba"), strategy.preferExtensionClassLoader(), strategy.overridden(), strategy.excludedPackages());
        }

        return extensionClasses;
    }

cacheDefaultExtensionName

    private void cacheDefaultExtensionName() {
        //获取注解类中上的SPI注解
        final SPI defaultAnnotation = type.getAnnotation(SPI.class);
        if (defaultAnnotation == null) {
            return;
        }
        //获取默认值SPI注解中的值 如@SPI("dubbo") @SPI(RandomLoadBalance.NAME) random
        String value = defaultAnnotation.value();
        if ((value = value.trim()).length() > 0) {
            String[] names = NAME_SEPARATOR.split(value);
            if (names.length > 1) {
                throw new IllegalStateException("More than 1 default extension name on extension " + type.getName()
                        + ": " + Arrays.toString(names));
            }
            if (names.length == 1) {
                //获取名称
                cachedDefaultName = names[0];
            }
        }
    }
loadDirectory

    /**
     * META-INF/dubbo/
     * META-INF/dubbo/internal/
     *   META-INF/services/
     * 从上面指定的位置加载扩展信息
     * 从这个文件夹中寻找真正的文件列表,并且对其中
     * 的文件内容解析并且放入到 extensionClasses Map中
     * dir META-INF/dubbo/internal/ 上面的路径
     * type 类的接口全路径 org.apache.dubbo.common.extension.ExtensionFactory
     */
    private void loadDirectory(Map<String, Class<?>> extensionClasses, String dir, String type,
                               boolean extensionLoaderClassLoaderFirst, boolean overridden, String... excludedPackages) {
        //文件名称规则: 路径/包名.接口名
        //META-INF/dubbo/internal/org.apache.dubbo.common.extension.ExtensionFactory
        String fileName = dir + type;
        try {
            //寻找classloader和url列表
            Enumeration<java.net.URL> urls = null;
            //ClassUtils.getClassLoader(ExtensionLoader.class)
            ClassLoader classLoader = findClassLoader();

            // try to load from ExtensionLoader's ClassLoader first
            if (extensionLoaderClassLoaderFirst) {
                //如果需要的话, 需要先从当前类的ClassLoader中寻找
                ClassLoader extensionLoaderClassLoader = ExtensionLoader.class.getClassLoader();
                if (ClassLoader.getSystemClassLoader() != extensionLoaderClassLoader) {
                    urls = extensionLoaderClassLoader.getResources(fileName);
                }
            }
            //如果找不到任何的URL列表,则继续尝试去其当前线程的ClassLoader中寻找
            if (urls == null || !urls.hasMoreElements()) {
                if (classLoader != null) {
                    urls = classLoader.getResources(fileName);
                } else {
                    urls = ClassLoader.getSystemResources(fileName);
                }
            }
            //如果存在文件的话
            if (urls != null) {
                while (urls.hasMoreElements()) {
                    java.net.URL resourceURL = urls.nextElement();
                    //遍历每一个资源文件,并且进行加载资源信息到extensionClasses, 主要功能是读取文件内容
                    loadResource(extensionClasses, classLoader, resourceURL, overridden, excludedPackages);
                }
            }
        } catch (Throwable t) {
            logger.error("Exception occurred when loading extension class (interface: " +
                    type + ", description file: " + fileName + ").", t);
        }
    }
loadResource

    //用于读取文件操作,并且将方法交由 loadClass 来加载类信息。加载类信息也是最重要的
    private void loadResource(Map<String, Class<?>> extensionClasses, ClassLoader classLoader,
                              java.net.URL resourceURL, boolean overridden, String... excludedPackages) {
        try {
            //读取文件
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(resourceURL.openStream(), StandardCharsets.UTF_8))) {
                String line;
                //一次读一行
                while ((line = reader.readLine()) != null) {
                    //判断 是有#号有注释 不要
                    final int ci = line.indexOf('#');
                    //如果有
                    if (ci >= 0) {
                        //截取#号前面的
                        line = line.substring(0, ci);
                    }
                    //判断line是否》0,有内容
                    line = line.trim();
                    if (line.length() > 0) {
                        try {
                            String name = null;
                            //分割
                            int i = line.indexOf('=');
                            //大于0有=号
                            if (i > 0) {
                                //=前是名称
                                name = line.substring(0, i).trim();
                                //=号后面是实现类的全路径
                                line = line.substring(i + 1).trim();
                            }
                            if (line.length() > 0 && !isExcluded(line, excludedPackages)) {
                                //加载类 对类信息进行加载操作
                                loadClass(extensionClasses, resourceURL, Class.forName(line, true, classLoader), name, overridden);
                            }
                        } catch (Throwable t) {
                            IllegalStateException e = new IllegalStateException("Failed to load extension class (interface: " + type + ", class line: " + line + ") in " + resourceURL + ", cause: " + t.getMessage(), t);
                            exceptions.put(line, e);
                        }
                    }
                }
            }
        } catch (Throwable t) {
            logger.error("Exception occurred when loading extension class (interface: " +
                    type + ", class file: " + resourceURL + ") in " + resourceURL, t);
        }
    }
loadClass
    //最终进行完成类映射的地方
    private void loadClass(Map<String, Class<?>> extensionClasses, java.net.URL resourceURL, Class<?> clazz, String name,
                           boolean overridden) throws NoSuchMethodException {
        //当前扩展点的实现,必须是当前扩展接口的实现才可以
        if (!type.isAssignableFrom(clazz)) {
            throw new IllegalStateException("Error occurred when loading extension class (interface: " +
                    type + ", class line: " + clazz.getName() + "), class "
                    + clazz.getName() + " is not subtype of interface.");
        }
        //判断当前类是否有Adaptive注释
        //如果是包含了Adaptive注解,则认为是需要对扩展点包装的方法,这里只做了存储操作,存储至cachedAdaptiveClass中
        if (clazz.isAnnotationPresent(Adaptive.class)) {
            cacheAdaptiveClass(clazz, overridden);
        } else if (isWrapperClass(clazz)) {
           // 判断是否是wapper类型, 是否构造函数中有该接口类型的传入
            // wrapper类型的意思是,对当前的扩展点实现封装功能处理
            cacheWrapperClass(clazz);
        } else {
            //创建实例
            //找他是否已经定义过了名称, 主要是获取当前类的
            //org.apache.dubbo.common.Extension注解,如果有的话就使用这个名称,否则的话就是用当前类的简单名称
            clazz.getConstructor();
            if (StringUtils.isEmpty(name)) {
                //获取注释中的名称
                name = findAnnotationName(clazz);
                if (name.length() == 0) {
                    throw new IllegalStateException("No such extension name for the class " + clazz.getName() + " in the config " + resourceURL);
                }
            }

            //否则的话,就对这个名称和class做映射关系
            String[] names = NAME_SEPARATOR.split(name);
            if (ArrayUtils.isNotEmpty(names)) {
                //如果当前类拥有Activate注解,则将其进行添加到cachedActivates对象中,意味着需要执行
                cacheActivateClass(clazz, names[0]);
                for (String n : names) {
                    //进行名称映射保存
                    cacheName(clazz, n);
                    saveInExtensionClass(extensionClasses, clazz, n, overridden);
                }
            }
        }
    }

当执行完这几个方法之后,会对一下几个字段进行更新

  • cachedAdaptiveClass: 当前Extension类型对应的AdaptiveExtension类型(只能一个)
  • cachedWrapperClasses: 当前Extension类型对应的所有Wrapper实现类型(无顺序)
  • cachedActivates: 当前Extension实现自动激活实现缓存(map,无序)
  • cachedNames: 扩展点实现类对应的名称(如配置多个名称则值为第一个)

根据name获取扩展点的方法 getExtension



     * 得到接口对应的 ExtensionLoader 对象之后会调用其 getExtension() 方法,根据传入的扩展名称从 cachedInstances 缓存中查找扩展实现的实例
     */
    @SuppressWarnings("unchecked")
    public T getExtension(String name) {
        if (StringUtils.isEmpty(name)) {
            //名称为空
            throw new IllegalArgumentException("Extension name == null");
        }
        if ("true".equals(name)) {
            //加载默认的扩展实现 如果name=true
            return getDefaultExtension();
        }
        //getOrCreateHolder()方法中封装了查找cachedInstances缓存的逻辑
        //获取当前类的holder,实现原理和cachedClasses的方式相同,都是建立同一个引用后再进行
		//加锁
        final Holder<Object> holder = getOrCreateHolder(name);
        Object instance = holder.get();
        //double-check防止并发问题
        if (instance == null) {
            synchronized (holder) {
                instance = holder.get();
                if (instance == null) {
                    //根据扩展名从SPI配置文件中查找对应的扩展实现类
                    //真正进行创建实例
                    instance = createExtension(name);
                    holder.set(instance);
                }
            }
        }
        return (T) instance;
    }
getOrCreateHolder 是如何保证缓存的

public class Holder<T> {

    private volatile T value;

    public void set(T value) {
        this.value = value;
    }

    public T get() {
        return value;
    }

}


    private Holder<Object> getOrCreateHolder(String name) {
        //根据名称获取实现
        Holder<Object> holder = cachedInstances.get(name);
        if (holder == null) {
            //为空就创建一个放入缓存中
            cachedInstances.putIfAbsent(name, new Holder<>());
            //再获取出来
            holder = cachedInstances.get(name);
        }
        return holder;
    }
createExtension 的实现,他是具体根据扩展的class名称来进行创建实例的


    private T createExtension(String name) {
        //从配置文件中加载所有的扩展类 可以得到配置项名称 到配置类的映射关系
        Class<?> clazz = getExtensionClasses().get(name);
        if (clazz == null) {
            throw findException(name);
        }
        try {
            //获取是否已经有实例了
            T instance = (T) EXTENSION_INSTANCES.get(clazz);
            if (instance == null) {
                //没有的话,同样适用putIfAbsent的方式来保证只会创建一个对象并且保存
                EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.newInstance());
                instance = (T) EXTENSION_INSTANCES.get(clazz);
            }
            // 注入其他扩展点的实体,用于扩展点和其他的扩展点相互打通
            injectExtension(instance);
            Set<Class<?>> wrapperClasses = cachedWrapperClasses;
            if (CollectionUtils.isNotEmpty(wrapperClasses)) {
                for (Class<?> wrapperClass : wrapperClasses) {
                    //进行遍历所有的包装类信息,分别对包装的类进行包装实例化,并且返回自身引用
                    // 同样进行注册其他扩展点的功能
                    instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
                }
            }
            //对扩展点进行初始化操作
            initExtension(instance);
            return instance;
        } catch (Throwable t) {
            throw new IllegalStateException("Extension instance (name: " + name + ", class: " +
                    type + ") couldn't be instantiated: " + t.getMessage(), t);
        }
    }
injectExtension
    private T injectExtension(T instance) {
        //检测objectFactory字段
        if (objectFactory == null) {
            return instance;
        }

        try {
            //遍历其中的所有方法
            for (Method method : instance.getClass().getMethods()) {
                //方法遍历判断是否为setter方法  如果不是,忽略该方法继续下一个方法
                if (!isSetter(method)) {
                // 是否是set方法
                // 1. 以"set"开头
                // 2. 参数长度为1
                // 3. 是公开的方法
                    continue;
                }
                /**
                 * Check {@link DisableInject} to see if we need auto injection for this property
                 */
                if (method.getAnnotation(DisableInject.class) != null) {
                    //判断是否禁止注入 如果方法上明确标注了@DisableInject注解,忽略该方法
                    continue;
                }
                //根据setter方法的参数,确定扩展接口
                Class<?> pt = method.getParameterTypes()[0];
                //判断是否为基本类型 原始类型(boolean、char、byte、short、int、long、float、double)
                //如果参数为简单类型,忽略该setter方法(略)
                if (ReflectUtils.isPrimitives(pt)) {
                    continue;
                }

                try {
                    //setter方法注入 获取需要set的扩展点名称
                    String property = getSetterProperty(method);
                    //从扩展中获取对象 加载并实例化扩展实现类
                    Object object = objectFactory.getExtension(pt, property);
                    //从ExtensionLoader中加载指定的扩展点
                     比如有一个方法为setRandom(LoadBalance loadBalance),那么则以为着需要加载负载均衡中名为random的扩展点
                    if (object != null) {
                        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;
    }
  • initExtension 展点进行初始化操作

    private void initExtension(T instance) {
        if (instance instanceof Lifecycle) {
            Lifecycle lifecycle = (Lifecycle) instance;
            lifecycle.initialize();
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值