您好,登录后才能下订单哦!
在Spring Boot的启动过程中,getSpringFactoriesInstances方法扮演了一个非常重要的角色。它负责从META-INF/spring.factories文件中加载并实例化指定的类。本文将深入分析getSpringFactoriesInstances方法的源码,并通过示例来展示其工作原理。
getSpringFactoriesInstances方法概述getSpringFactoriesInstances方法是Spring Boot中用于加载和实例化spring.factories文件中配置的类的方法。它通常用于加载Spring Boot的自动配置类、初始化器、监听器等。
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) {
    // 方法实现
}
type: 需要加载的类类型,通常是接口或抽象类。parameterTypes: 构造函数的参数类型。args: 构造函数的参数值。getSpringFactoriesInstances方法源码分析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;
}
getClassLoader()方法获取当前线程的上下文类加载器。SpringFactoriesLoader.loadFactoryNames方法从META-INF/spring.factories文件中加载指定类型的类名。createSpringFactoriesInstances方法实例化这些类。AnnotationAwareOrderComparator.sort方法对实例进行排序。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());
}
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;
}
AnnotationAwareOrderComparator.sort方法AnnotationAwareOrderComparator.sort方法负责对实例化的对象进行排序。
public static void sort(List<?> list) {
    if (list.size() > 1) {
        list.sort(INSTANCE);
    }
}
假设我们有一个Spring Boot应用,需要在启动时加载并实例化一些自定义的初始化器。这些初始化器定义在META-INF/spring.factories文件中。
META-INF/spring.factories文件内容org.springframework.context.ApplicationContextInitializer=\
com.example.MyInitializer1,\
com.example.MyInitializer2
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");
    }
}
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);
        }
    }
}
当Spring Boot应用启动时,控制台将输出:
MyInitializer1 is initialized
MyInitializer2 is initialized
通过本文的分析,我们了解了getSpringFactoriesInstances方法在Spring Boot中的作用及其实现原理。该方法通过加载META-INF/spring.factories文件中的配置,实例化指定的类,并对这些实例进行排序。通过示例,我们展示了如何使用该方法加载自定义的初始化器,并在应用启动时执行这些初始化器。
getSpringFactoriesInstances方法是Spring Boot自动配置机制的核心之一,理解其工作原理对于深入掌握Spring Boot的启动过程至关重要。希望本文的分析能够帮助读者更好地理解和使用Spring Boot。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。