我正在阅读SpringApplication.java
的源代码。我以一种复杂的方式加载ApplicationContextInitializer
和ApplicationListener
:
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
关键字创建这些工厂实例?
答案 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原则(松散耦合,依赖注入)。