springboot中getSpringFactoriesInstances源码的示例分析

发布时间:2021-11-24 17:44:25 作者:小新
来源:亿速云 阅读:232

SpringBoot中getSpringFactoriesInstances源码的示例分析

引言

在Spring Boot的启动过程中,getSpringFactoriesInstances方法扮演了一个非常重要的角色。它负责从META-INF/spring.factories文件中加载并实例化指定的类。本文将深入分析getSpringFactoriesInstances方法的源码,并通过示例来展示其工作原理。

1. getSpringFactoriesInstances方法概述

getSpringFactoriesInstances方法是Spring Boot中用于加载和实例化spring.factories文件中配置的类的方法。它通常用于加载Spring Boot的自动配置类、初始化器、监听器等。

1.1 方法签名

protected <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {
    return getSpringFactoriesInstances(type, new Class<?>[] {});
}

protected <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
    // 方法实现
}

1.2 方法参数

2. getSpringFactoriesInstances方法源码分析

2.1 方法实现

protected <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
    ClassLoader classLoader = getClassLoader();
    // 使用SpringFactoriesLoader加载指定类型的类名
    Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
    // 实例化这些类
    List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
    // 对实例进行排序
    AnnotationAwareOrderComparator.sort(instances);
    return instances;
}

2.2 方法步骤

  1. 获取类加载器: 使用getClassLoader()方法获取当前线程的上下文类加载器。
  2. 加载类名: 使用SpringFactoriesLoader.loadFactoryNames方法从META-INF/spring.factories文件中加载指定类型的类名。
  3. 实例化类: 使用createSpringFactoriesInstances方法实例化这些类。
  4. 排序实例: 使用AnnotationAwareOrderComparator.sort方法对实例进行排序。
  5. 返回实例: 返回实例化的对象集合。

2.3 SpringFactoriesLoader.loadFactoryNames方法

SpringFactoriesLoader.loadFactoryNames方法负责从META-INF/spring.factories文件中加载指定类型的类名。

public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
    String factoryTypeName = factoryType.getName();
    return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}

2.4 createSpringFactoriesInstances方法

createSpringFactoriesInstances方法负责实例化从spring.factories文件中加载的类。

private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, ClassLoader classLoader, Object[] args, Set<String> names) {
    List<T> instances = new ArrayList<>(names.size());
    for (String name : names) {
        try {
            Class<?> instanceClass = ClassUtils.forName(name, classLoader);
            Assert.isAssignable(type, instanceClass);
            Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);
            T instance = (T) BeanUtils.instantiateClass(constructor, args);
            instances.add(instance);
        } catch (Throwable ex) {
            throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, ex);
        }
    }
    return instances;
}

2.5 AnnotationAwareOrderComparator.sort方法

AnnotationAwareOrderComparator.sort方法负责对实例化的对象进行排序。

public static void sort(List<?> list) {
    if (list.size() > 1) {
        list.sort(INSTANCE);
    }
}

3. 示例分析

3.1 示例场景

假设我们有一个Spring Boot应用,需要在启动时加载并实例化一些自定义的初始化器。这些初始化器定义在META-INF/spring.factories文件中。

3.2 META-INF/spring.factories文件内容

org.springframework.context.ApplicationContextInitializer=\
com.example.MyInitializer1,\
com.example.MyInitializer2

3.3 自定义初始化器

public class MyInitializer1 implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        System.out.println("MyInitializer1 is initialized");
    }
}

public class MyInitializer2 implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        System.out.println("MyInitializer2 is initialized");
    }
}

3.4 使用getSpringFactoriesInstances方法加载初始化器

public class MySpringApplication extends SpringApplication {
    public MySpringApplication(Class<?>... primarySources) {
        super(primarySources);
    }

    @Override
    protected void applyInitializers(ConfigurableApplicationContext context) {
        Collection<ApplicationContextInitializer<?>> initializers = getSpringFactoriesInstances(ApplicationContextInitializer.class);
        for (ApplicationContextInitializer<?> initializer : initializers) {
            initializer.initialize(context);
        }
    }
}

3.5 运行结果

当Spring Boot应用启动时,控制台将输出:

MyInitializer1 is initialized
MyInitializer2 is initialized

4. 总结

通过本文的分析,我们了解了getSpringFactoriesInstances方法在Spring Boot中的作用及其实现原理。该方法通过加载META-INF/spring.factories文件中的配置,实例化指定的类,并对这些实例进行排序。通过示例,我们展示了如何使用该方法加载自定义的初始化器,并在应用启动时执行这些初始化器。

getSpringFactoriesInstances方法是Spring Boot自动配置机制的核心之一,理解其工作原理对于深入掌握Spring Boot的启动过程至关重要。希望本文的分析能够帮助读者更好地理解和使用Spring Boot。

推荐阅读:
  1. React中setState源码的示例分析
  2. Bootstrap中Scrollspy源码的示例分析

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

springboot

上一篇:如何理解Vue的监听属性

下一篇:Protobuf工具在C#中的使用方法是什么

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》