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);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
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;
}
从方法名称就能知道,这个方法是得到spring.factories文件的实例化对象
参数:type的类名为key,也就是上图黄色的部分,真正实例化的类是上图中绿色的部分。parameterTypes为构造器的参数类型。args为构造方法中参数的值。
获取到ClassLoader,通过ClassLoader加载到所有的META-INF/spring.factories文件资源。Properties#load拿到key value信息,type为key(途中黄色部分),value逗号分隔返回Set去重后的类名。通过反射创建实例。
在解析spring.factories文件的过程中,第一次就将所有的spring.factories文件加载了,对classLoader进行了缓存,避免重复加载创建多个实例。
在SpringBoot启动的过程中,spring.factories资源在一开始就被解析了。