springboot中getSpringFactoriesInstances源码的示例分析
发表于:2025-12-03 作者:千家信息网编辑
千家信息网最后更新 2025年12月03日,这篇文章主要介绍了springboot中getSpringFactoriesInstances源码的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带
千家信息网最后更新 2025年12月03日springboot中getSpringFactoriesInstances源码的示例分析image image
这篇文章主要介绍了springboot中getSpringFactoriesInstances源码的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
一、概述及流程图
在springboot启动过程中,getSpringFactoriesInstances这个方法很重要,启动的时候使用该方法从classpath上所有jar包中找出对应的META-INF/spring.factorys属性文件,并将其中的初始化器和监听器加载并实例化,应用于更进一步的初始化工作。其工作流程图如下:
二、源码解析
让我们跟着流程图和时序图一步步窥视其中的奥妙:
调用getSpringFactoriesInstances()方法
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();
//1.加载初始化器并实例化,10.并赋值给initializers
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
//同上,监听器
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
//推断应用主类
this.mainApplicationClass = deduceMainApplicationClass();
}
获取类加载器和调用loadFactoryNames()方法及对返回结果进行初始化以及排序
private Collection getSpringFactoriesInstances(Class type) {
return getSpringFactoriesInstances(type, new Class>[] {});
}
private Collection getSpringFactoriesInstances(Class type, Class>[] parameterTypes, Object... args) {
//2. 获取类加载器
ClassLoader classLoader = getClassLoader();
// Use names and ensure unique to protect against duplicates
//3. 调用loadFactoryNames方法,并使用set对其返回结果进行去重处理
Set names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
//9. 实例化初始化器
List instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
//9. 对实例化的结果进行排序
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
//该方法主要是通过反射实例化初始化器
private List createSpringFactoriesInstances(Class type, Class>[] parameterTypes,
ClassLoader classLoader, Object[] args, Set names) {
List 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;
}
查询缓存和读取META-INFO/spring.factorys文件key-value值,并对value值进行处理
public static List loadFactoryNames(Class> factoryClass, @Nullable ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
// 返回初始化器的value值
return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}
private static Map> loadSpringFactories(@Nullable ClassLoader classLoader) {
MultiValueMap result = //查询缓存,如果有就返回,没有就加载
cache.get(classLoader);
if (result != null) {
return result;
}
try {
//通过类加载器加载所有jar包中包含META-INFO/spring.factorys的文件资源路径
Enumeration urls = (classLoader != null ?
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);
//实例化properties对象,并加载路径中的spring.factorys文件内容
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
for (Map.Entry, ?> entry : properties.entrySet()) {
String factoryClassName = ((String)
//获取key值
entry.getKey()).trim();
//对value值进行都好拆分处理
for (String factoryName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
//将key和value值存入result中 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);
}
} 感谢你能够认真阅读完这篇文章,希望小编分享的"springboot中getSpringFactoriesInstances源码的示例分析"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!
实例
方法
文件
篇文章
结果
源码
流程
流程图
缓存
路径
处理
示例
分析
监听器
资源
工作
应用
排序
推断
查询
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
网络安全等级保护商用密码
北京电脑服务器机箱加工云主机
行车记录软件开发的上市公司
软件开发测试是什么行业
服务器稳定工作时间
网络安全队伍名
湛江微信软件开发费用是多少
海康服务器81端口
怎么把静态资源服务器地址添加到项目里
互联网黑科技比赛
属性对应于数据库中的
北京金橙子科技软件开发工程师
嘉兴网络技术咨询费用
数据库er图详细点怎么画
义乌市信圣网络技术研发
软件开发加工
万通达网络技术有限公司
影视加速服务器怎么开启
广东戴尔服务器虚拟化费用
cmd创建python服务器
dna数据库保存
玉林软件开发招聘
通辽软件开发专业
白嫖阿里云一年服务器
陕西省监狱管理局服务器
网络安全日常工作运行机制
ios变声软件开发
北京百度网络技术有限公司
服务器logs文件夹是什么意思
数据库单个用户下无法访问