org.springframework.core.io.support.SpringFactoriesLoader
/**
* General purpose factory loading mechanism for internal use within the framework.
*
* <p>{@code SpringFactoriesLoader} {@linkplain #loadFactories loads} and instantiates
* factories of a given type from {@value #FACTORIES_RESOURCE_LOCATION} files which
* may be present in multiple JAR files in the classpath. The {@code spring.factories}
* file must be in {@link Properties} format, where the key is the fully qualified
* name of the interface or abstract class, and the value is a comma-separated list of
* implementation class names. For example:
*
* <pre class="code">example.MyService=example.MyServiceImpl1,example.MyServiceImpl2</pre>
*
* where {@code example.MyService} is the name of the interface, and {@code MyServiceImpl1}
* and {@code MyServiceImpl2} are two implementations.
*
* @author Arjen Poutsma
* @author Juergen Hoeller
* @author Sam Brannen
* @since 3.2
*/
public final class SpringFactoriesLoader {- 框架内部使用的通用工厂加载机制
- 从classpath 下多个jar包特定的位置读取文件并初始化类
- 文件内容必须是kv形式,即properties类型
- key是全限定名(抽象类|接口)、value是实现,多个实现用逗号分隔
@SuppressWarnings({ "unchecked", "rawtypes" })
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 通过setInitializers#()方法,设置系统初始化器
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
} private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
// 获得类加载器
ClassLoader classLoader = getClassLoader();
// 通过这个SpringFactoriesLoader#loadFactoryNames方法获取Spring中所有系统初始化器实现的全路径名
Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
// #()创建它们的实例
List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
// 通过注解@Order进行排序
AnnotationAwareOrderComparator.sort(instances);
return instances;
} private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
MultiValueMap<String, String> result = cache.get(classLoader);
// 检查是否有缓存
if (result != null) {
return result;
}
try {
Enumeration<URL> urls = (classLoader != null ?
// 获取 META-INF/spring.factories下所有系统初始化器的实现
classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
result = new LinkedMultiValueMap<>();
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
UrlResource resource = new UrlResource(url);
// 通过url路径,获取spring.factories中的配置,并将其转成Properties格式
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
for (Map.Entry<?, ?> entry : properties.entrySet()) {
String factoryClassName = ((String) entry.getKey()).trim();
for (String factoryName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
// 将初始化器的包名进行返回
result.add(factoryClassName, factoryName.trim());
}
}
}
// 记录到缓存中
cache.put(classLoader, result);
return result;
}
catch (IOException ex) {
throw new IllegalArgumentException("Unable to load factories from location [" +
FACTORIES_RESOURCE_LOCATION + "]", ex);
}
} @SuppressWarnings("unchecked")
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;
} private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = getClassLoader();
// Use names and ensure unique to protect against duplicates
Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
// 按@Order注解进行排序,值约小的越靠前
AnnotationAwareOrderComparator.sort(instances);
return instances;
} public void setInitializers(Collection<? extends ApplicationContextInitializer<?>> initializers) {
this.initializers = new ArrayList<>();
// 将初始化器的实例添加到Spring容器中
this.initializers.addAll(initializers);
}- SpringFactoriesLoader作用: SpringBoot框架中从类路径jar包中读取特定的文件(META-INF/spring.factories)实现扩展类的载入
- LoadFactories流程


