首页 > 美食

SpringBoot spring.factories加载时机分析_今日热搜

来源:脚本之家 时间:2023-06-24 16:49:46

目录
spring.factories作用源码解析用法

spring.factories作用

这个类似于Java中的SPI功能,SpringBoot启动的时候会读取所有jar包下面的META-INF/spring.factories文件;

并且将文件中的 接口/抽象类 对应的实现类都对应起来,并在需要的时候可以实例化对应的实现类

下面我们来分析一下源码看看spring.factories的使用场景


(相关资料图)

源码解析

启动SpringApplication,看看构造方法

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((Collection) getSpringFactoriesInstances(
				ApplicationContextInitializer.class));
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		this.mainApplicationClass = deduceMainApplicationClass();
	}

其中方法getSpringFactoriesInstances( ApplicationContextInitializer.class)是用于获取Spring中指定类实例用的;并且获取的时候是根据读取整个项目中文件路径为META-INF/spring.factories中的内容实例化对应的实例类的;

例如这里的ApplicationContextInitializer是一个接口,那么应该实例化哪些他的实现类呢?那就找META-INF/spring.factories文件 ; 那么我们在spring-boot:2.1.0jar包中找到了这个文件

读取到需要实例化的实现类为

org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer

并且还在spring-boot-autoconfigure-2.1.0.RELEASE.jar中找到了这个文件

那么文件中的两个实现类也会被实例化;加上上面4个总共有6个

org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener

可以看到不仅仅只是把org.springframework.context.ApplicationContextInitializer 的实例类解析了出来;而是所有的都解析了出来并且保存下来了.下次其他的类需要被实例化的时候就可以直接从内存里面拿了;

上面过程拿到了实例类之后,接下来就是实例化的过程了

private  Collection getSpringFactoriesInstances(Class type,
			Class[] parameterTypes, Object... args) {
		ClassLoader classLoader = getClassLoader();
		// Use names and ensure unique to protect against duplicates
		Set names = new LinkedHashSet<>(
				SpringFactoriesLoader.loadFactoryNames(type, classLoader));
		List instances = createSpringFactoriesInstances(type, parameterTypes,
				classLoader, args, names);
		AnnotationAwareOrderComparator.sort(instances);
		return instances;
	}

方法createSpringFactoriesInstances就是创建实例的过程;可以看到传入了对应的接口类org.springframework.context.ApplicationContextInitializer ;接下来就会实例化 上面找到了对应的实现类;

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;
	}

实例化的过程如果,没有什么特别需要讲解的;

上面有个方法AnnotationAwareOrderComparator.sort(instances);是用来排序所有实例的; 实现类需要实现 接口Ordered; getOrder返回的值越小,优先级更高

用法

知道spring.factories的用法之后, 那么我们就可以利用这个特性实现自己的目的;

例如我们也可以写一个接口类ApplicationContextInitializer的实现类;

等等之类的;

以上就是SpringBoot spring.factories加载时机分析的详细内容,更多关于spring.factories加载时机的资料请关注脚本之家其它相关文章!

相关稿件

SpringBoot spring.factories加载时机分析_今日热搜

600667股票

白宫:正密切关注俄罗斯局势,拜登已听取简报 每日简讯

测运势2022年运势免费,紫微免费算2022年运势|环球观察

观察:每日热闻!今日热门!北京市教委:高温天气下合理调整学生室外活动时间 根据实际情况采取减课或停课措施 热点评_全球播资讯 全球简讯 每日观点

当前要闻:推动品牌建设上台阶

俄罗斯总统普京发表讲话

新资讯:关系户来了?勇士新秀的经纪人竟然是勇士总经理的亲弟弟?

享誉:哈尔滨专业治疗疤痕医院排名[大胆公开]哈尔滨哪家医院无痕祛疤好|当前消息

强化审判能力建设 延伸司法保障职能 ——新疆知识产权保护水平稳步提升 天天精选

美国“里根”号航母将停靠越南港口,越方称“正常友好交流”

浙江科技学院怎么样 浙江科技学院地址是什么

《星空》浪漫关系新细节:可"抛弃"同伴 独立单身

每日讯息!王力宏李云迪罗志祥_王力宏李云迪斗琴

【短讯】“瓦格纳”首领称其部队已进入俄境内!一文梳理这场“叛乱”经过……

中国经济中长期前景POLL(2023年5月/PB):经济、政策双平稳成新主流预期

环球新动态:南京市医保局用新思想指引南京医保新实践

全球快看:2023年端午档总票房突破8亿

威观宁夏:保险赔付1400万很多吗?对于普通人来说,购买商业保险是最简单有效的抵御风险的行为吧?

今冬投运!海阳至乳山核能供热工程最新进展来了 每日快讯

【世界播资讯】年销粽子600万个!古老“粽子村”里的变与不变

范丞丞的“自私”,让观众看清白鹿的为人,《跑男》因此话题出圈 每日视点

世界热资讯!移动硬盘格式化后能恢复数据吗(请将磁盘插入可移动磁盘)

胥姓氏读kang还是hang(胥)

【播资讯】保险公司的注册资本需要多少

古装厂牌到全能玩家,年均爆款的西嘻影业提供了影视公司的生存法

民营企业法律风险防控提示书怎样规定?

买手机就选16+512G大内存,这3款都是骁龙8+芯片,关键价格还不贵

突发!国泰航空一客机突发故障,11人逃生途中受伤送医!女乘客还原惊恐一幕:有人打电话给父母一直哭,有一个妈妈抱着孩子一直说对不起……

通讯!欧盟通过第11轮对俄制裁,俄外交部:制裁非法,已及时回应