SpringBoot 基础概念:SpringApplication#getSpringFactoriesInstances

发布时间:2023年12月18日

SpringBoot 基础概念:SpringApplication#getSpringFactoriesInstances

SpringApplication#getSpringFactoriesInstances

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;
}
  1. 从方法名称就能知道,这个方法是得到spring.factories文件的实例化对象
    在这里插入图片描述

  2. 参数:type的类名为key,也就是上图黄色的部分,真正实例化的类是上图中绿色的部分。parameterTypes为构造器的参数类型。args为构造方法中参数的值。

  3. 获取到ClassLoader,通过ClassLoader加载到所有的META-INF/spring.factories文件资源。Properties#load拿到key value信息,type为key(途中黄色部分),value逗号分隔返回Set去重后的类名。通过反射创建实例。

  4. 在解析spring.factories文件的过程中,第一次就将所有的spring.factories文件加载了,对classLoader进行了缓存,避免重复加载创建多个实例。

  5. 在SpringBoot启动的过程中,spring.factories资源在一开始就被解析了。

文章来源:https://blog.csdn.net/java_xiaoba1/article/details/135018571
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。