为什么SpringApplication通过config加载ApplicationContextInitializer?

时间:2018-02-02 08:18:11

标签: java spring spring-boot

我正在阅读SpringApplication.java的源代码。我以一种复杂的方式加载ApplicationContextInitializerApplicationListener

private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type,
        Class<?>[] parameterTypes, Object... args) {
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    // Use names and ensure unique to protect against duplicates
    Set<String> names = new LinkedHashSet<String>(
            SpringFactoriesLoader.loadFactoryNames(type, classLoader));
    List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
            classLoader, args, names);
    AnnotationAwareOrderComparator.sort(instances);
    return instances;
}

为什么不按new关键字创建这些工厂实例?

2 个答案:

答案 0 :(得分:2)

Spring bean的默认范围始终是singleton。 Spring Singleton在上下文或容器中是唯一的。例如,在您的示例中,它似乎是每个上下文的一个实例:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// Use names and ensure unique to protect against duplicates
Set<String> names = new LinkedHashSet<String>(
                SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
                classLoader, args, names);

最后一行:

AnnotationAwareOrderComparator.sort(instances);

正如我想的那样,订购加载实例:

  

创作的顺序对于Spring很重要。消化后   配置元数据,Spring创建一个计划(它分配一定的   每个bean的优先级)以及需要的bean的顺序   创建以满足依赖性。

它之所以成为AnnotationAwareOrderComparator,是因为Spring中的多种组件都支持基于注释的排序。 例如(section 44.2):

  

您可以使用@AutoConfigureAfter或@AutoConfigureBefore   如果您的配置需要应用于特定的注释   顺序。

答案 1 :(得分:1)

我认为背后的原因是松散耦合和可重用性,ApplicationContextInitializer是接口,Spring应用程序中有许多类,如AutoConfigurationReportLoggingInitializer,ConfigFileApplicationContextInitializer,ContextCustomizerAdapter等等,它们正在实现ApplicationContextInitializer, 因此,如果他们使用new关键字,那么它就是紧密耦合,这违反了自己的spring原则(松散耦合,依赖注入)。