源代码分析 spring.factories 的使用原理和实现自动装配

Spring的Factories机制介绍 在看本节文章之前,建议大家先去了一下java的SPI机制,因为Spring的Factories就是Spring版本的Java Spi,我在关于java基础系列文章中有详细介绍Java SPI机制。 Spring Factories的最重要的功能就是:可以通过配置文件指定Spring容器加载一些特定的组件。 基本概念 什么是Spring Factories Spring Factories是一种类似于Java SPI的机制,它在META-INF/spring.factories文件中配置接口的实现类名称,然 阅读详情

源代码分析 spring.factories 的使用原理和实现自动装配

一、Spring Boot是如何使用spring.factories文件的呢?

0.Spring Boot仿照Java中的SPI扩展机制实现了自己的扩展机制。它在META-INF/spring.factories文件中配置接口的实现类名称,然后在程序中读取这些配置文件并实例化。这种自定义的SPI机制是Spring Boot Starter实现的基础。

1.SpringFactoriesLoader类
spring-core包里定义了SpringFactoriesLoader类,这个类实现了检索META-INF/spring.factories文件,并获取指定接口的配置的功能。在这个类中定义了两个对外的方法:
loadFactories() 和 loadFactoryNames() ,loadFactories()方法中也是调用了loadFactoryNames()。

2.源代码


	private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
		MultiValueMap<String, String> result = cache.get(classLoader);
		if (result != null) {
			return result;
		}

		try {
		
		    /**
		      * public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
		      */
			Enumeration<URL> 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 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);
		}
	}


从代码中我们可以知道,在这个方法中会遍历整个ClassLoader中所有jar包下的spring.factories文件。也就是说我们可以在自己的jar中配置spring.factories文件,不会影响到其它地方的配置,也不会被别人的配置覆盖。

二.使用spring.factories来实现自动装配。

0.对于我们添加的依赖,我们可以手动来配置这些jar包所需要的bean;同时呢,我们也可以spring.factories来实现自动装配。相比于手写的方式,这样做的好处就是在构建大型项目的时候,有时你可能会自己写一个外部依赖包(类似spring-boot-starter-xxx)。主项目添加这个外部依赖包后,这个外部依赖包里面的bean如果需要自动加入主项目的spring容器中(而不必手动添加@Bean实例化)。

1.如何使用spring.factories来实现自动装配的呢?

2.@SpringBootApplication注解


@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
    ...
}

    在源码里,@EnableAutoConfiguration 这个注解是关键。我们知道一般@Enable…开头的注解多是开关,含义是开启… 这里的含义就是开启自动配置。


@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

	String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

	/**
	 * Exclude specific auto-configuration classes such that they will never be applied.
	 * @return the classes to exclude
	 */
	Class<?>[] exclude() default {};

	/**
	 * Exclude specific auto-configuration class names such that they will never be
	 * applied.
	 * @return the class names to exclude
	 * @since 1.3.0
	 */
	String[] excludeName() default {};

}


    在源码里,可以看到它引入了AutoConfigurationImportSelector类。


	protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
			AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return EMPTY_ENTRY;
		}
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
		
		
		List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
		
		
		configurations = removeDuplicates(configurations);
		Set<String> exclusions = getExclusions(annotationMetadata, attributes);
		checkExcludedClasses(configurations, exclusions);
		configurations.removeAll(exclusions);
		configurations = filter(configurations, autoConfigurationMetadata);
		fireAutoConfigurationImportEvents(configurations, exclusions);
		return new AutoConfigurationEntry(configurations, exclusions);
	}


	protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
		List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
				getBeanClassLoader());
		Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
				+ "are using a custom packaging, make sure that file is correct.");
		return configurations;
	}

	protected Class<?> getSpringFactoriesLoaderFactoryClass() {
		return EnableAutoConfiguration.class;
	}

    在源码里,我们可以发现,上面这三个方法说明了获取自动装配的过程:SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),getBeanClassLoader())
    因此我们在使用spring.factories来实现自动装配时,可以在spring.factories文件中添加这样的键值对.


org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.portal.web.autoconfigure.DevelopmentDomainAutoConfigure

    key 是 EnableAutoConfiguration 的全路径名,value是我们自己定义文件的路径名。
这样,我们就可以实现jar包中bean的自动装配。

一篇博客搞懂spring.factories的基本概念和使用 spring.factories 是,用于定义和加载 Spring Boot 自动配置类、监听器、环境后处理器等。它通常位于 META-INF 目录下。 阅读详情

相关推荐

Spring Boot架构篇 - 自动装配机制

本文介绍Spring Boot的自动装配原理。

The Secret 638

小明学Spring基础系列——Spring Factories机制

Spring Factories是一种类似于Java SPI的机制,它在META-INF/spring.factories文件中配置接口的实现类名称,然后在程序中读取这些配置文件并实例化。

小明的博客 1325

三分钟了解springBoot 之spring.factories扩展机制

如果只是需要应付面试或者只是想大概了解,看完此章节就可以了复制代码。

m0_71777195的博客 347

SpringBoot源码分析(二):spring.factories 文件

文章目录spring.factories文件内容摘选自动加载机制简介各接口简介org.springframework.context.ApplicationContextInitializerorg.springframework.context.ApplicationListenerorg.springframework.boot.SpringApplicationRunListenerorg.springframework.boot.autoconfigure.AutoConfigurationImpo

MengFly的博客 3121

【springboot】为何不使用@EnableTransactionManagement就能使用事务?

在Springboot项目开发时,假如:公司项目比较多,从事开发的同学也会相应的比较多,如果公司没有统一的开发规范,我们使用的技术就会花里胡哨,不知道看到本篇博客的您,是否有所感想,

知识改变命运,ヾ(◍°∇°◍)ノ゙【求关注】 2万+

NotebookLM平替实测:用Open Notebook+Ollama零成本搭建私有AI知识库

本文提供了一份详细的实战指南,教你如何利用Open Notebook与Ollama,在本地零成本搭建一个功能强大且完全私有的AI知识库。通过Docker容器化部署,实现数据绝对安全、模型自由选择与离线运行,是NotebookLM等云端工具的绝佳平替方案,尤其适合注重数据隐私的教育工作者、研究者及小团队。

weixin_29052717的博客 513

SpringBoot:运行原理探究

文章目录使用IDEA快速构建项目1. Idea建立SpringBoot项目1. 创建一个新项目2. 选择spring initalizr , 可以看到默认就是去官网的快速构建工具那里实现3. 和之前一样填写项目信息4. 选择初始化的组件5.填写项目路径6.等待项目构建成功2. 测试HelloSpring 使用IDEA快速构建项目 1. Idea建立SpringBoot项目 之前,我们在官网上直接快...

weixin_43306403的博客 397

LaTeX小白必看:5分钟搞定GB/T 7714-2005参考文献格式(Texmaker+BibTeX实战)

本文为LaTeX初学者提供了使用Texmaker编辑器和BibTeX工具链,快速实现GB/T 7714-2005参考文献格式的实战指南。文章详细解析了从获取gbt7714-2005.bst样式文件、编写.bib数据库到四步编译流程的核心步骤,并附有常见问题解决方案,帮助用户高效、准确地完成学术论文的参考文献排版。

weixin_29295541的博客 338

为什么SpringBoot 3中移除了spring.factories

通过创建实现Processor接口的注解处理器,开发者可以在源代码编译阶段读取注解信息,并根据注解生成新的源代码或资源文件。在SpringBoot 2.7中,官方已经明确的说了,使用spring.factories这种自动配置的方式已经过时了,并且将在SpringBoot 3.0中彻底移除。这是因为Spring 2.7之后,不仅新增了这种配置方式,还提供了一个新的注解,就是这个。的方式,它允许在编译时检查、处理注解,并且可以生成新的源代码、资源文件或其他文件。我们知道,云原生时代中,最重要的是什么?

埃泽漫笔 1761

【虚拟化生态平台】虚拟化平台esxi挂载USB硬盘

虚拟化平台安装好之后,一般情况下,只有一个硬盘在工作,其他的外接硬盘(我的只有一个ssd硬盘,其他的均是usb外接,SATA接口的硬盘是否这样我暂时不清楚哈)没有在工作,但是一个硬盘明显不够我们使用的,所以我们需要去挂载外接的硬盘来扩容。...

Rubik Blog 4834

接入穿山甲SDK时,Unity打Android包报错日志

SDK工程设置为Enable,项目工程设置为Disable。2、将unitypackage导入包名为:com.DefaultCompany.Myproject的另一个工程,打包报错。3、点击工程默认弹出Enable Android Auto-resolution 设置选项,点击Enable。1、新建一个空工程,设置包名为:com.ceshi.hewen,正常打包无报错,导出unitypackage。2、点击Reset to Defaults 重置参数,再点击ok关闭设置窗口。

不文不武的禾文 3583

SpringBoot自动装配原理

Spring Boot 是一个可以轻松创建独立的、生产级的基于 Spring 的应用程序的框架,Spring Boot 框架将 Spring、MyBatis、SpringMVC 中的一系列配置进行了简化,只需要使用最简单的配置和注解就能快速开发应用程序。Spring Boot 框架就会自动引入 web 环境所有的依赖,并且自动配置,Spring Boot 将所有的功能场景,都变成一个个启动器,想要用什么功能,只需要找到对应的启动器就可以了。Spring Boot 中的一系列启动器是自动装配的最佳实践。

一个双子座的Java攻城狮 1036

菜鸟哥玩蓝牙Ble4.0系列 ESP32初玩篇③ Beacon —— 广播应用,室内定位,内容推送

文章目录1、前言1.1 什么叫做Beacon?1.2 Beacon使用场景1.3 Beacon协议落地实现2、ESP32 Beacon案例3、Beacon核心库 —— BLEBeacon、BLEEddystoneTLM、BLEEddystoneURL3.1 BLEBeacon3.2 BLEEddystoneTLM3.3 BLEEddystoneURL 授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力。希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石。。。

单片机菜鸟哥的博客 2万+

Spring-boot之启动原理--源码分析+实现ApplicationContextInitializer和SpringApplicationRunListener

阿斯达

大雄君的博客 782

静态代码审计插件 snyk 使用教程

静态代码审计插件 snyk 使用教程

SHELLCODE_8BIT的博客 2003

uni-app开发-第3篇:uni-app 页面与路由

本文详细介绍了 uni-app 中的页面开发与路由管理。首先,页面是应用的基础单元,创建页面时需在pages目录下新建文件夹和.vue文件,页面结构由<template>、<script>和<style>三部分组成。uni-app 页面生命周期函数包括onShow、onReady、onHide和onUnload,分别用于处理页面显示、渲染完成、隐藏和卸载时的逻辑。其次,路由管理通过pages.json文件配置页面路径和样式,并提供uni.navigateTo等方法进行路由

无 415

一文详解SpringBoot自动装配原理

自动装配原理实际上就是通过注解,加载类中的方法,进而扫描MATE-INF下的文件下的自动配置类,并将其装配至Spring IOC容器的过程。作者:austin流川枫链接:https://juejin.cn/post/7111341858306949127来源:稀土掘金著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2301_76607156的博客 380

2024年下半年网络规划设计师论文真题

3、深入论述自身参与的工业网络是如何实施的,为实现制造业的智能化,如何实现数据的跨系统互通,促进各种工业数据的充分流动和无缝集成以及数据安全。3、结合自身参与的网络建设,详细叙述针对该网络“去NAT”的规划和设计方案。4、在实施过程中遇到的问题以及如何处理,项目实施后的效果和评价。2、大型园区网络“去NAT”改造和业务融合的整体架构。1、“网络去NAT”对推进ipv6演进和应用的意义。4、改造过程中遇到的问题及解决方案。2、简要叙述自身参与的制造网络建设。1、网络规划在智能制造中的意义。

鹿鸣天涯 2365

SpringBoot自动装配源码分析

当我们在Spring Boot应用中添加了该注解时,Spring Boot会根据约定大于配置的原则,自动配置一些常用的Bean和组件,从而简化开发流程。最后,根据一些条件对自动配置类进行过滤,并返回一个包含候选自动配置类和已排除自动配置类的。通过这种方式,Spring Boot能够根据约定大于配置的原则,自动加载和配置常用的Bean和组件,使开发者能够更加便捷地构建和部署应用程序。在这个方法中,它首先判断是否启用了自动装配,然后加载自动配置的元数据,并获取自动配置的入口。最后,返回自动配置的类名数组。

lj872224的博客 411

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

SpringBoot:使用Spring Factories加载JAR中的配置类机制分析

在使用SpringBoot时,使用Spring Factories加载JAR中的配置类机制分析

netyeaxi的专栏 1315

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

SpringBoot系列:自动装配原理分析

序言 不管在工作中还是在求职面试中,SpringBoot成为了我们必会的知识技能之一。当然,作为Spring Boot的精髓,自动配置原理首当其冲。在本文章的下面,也是自己在源代码中挣扎的一些简单理解。 原理分析 首先打开一个基本的springboot项目,我们可以看到@SpringBootApplication,说明这个类是SpringBoot的主配置类,SpringBoot就会运行这个类的main方法来启动SpringBoot项目: 点进去@SpringBootApplication注解,我们

小唐的博客 271

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Spring Boot自动装配源码分析

Spring Boot 的自动装配(Auto-Configuration)是其核心特性之一,它通过条件化配置和默认值,实现了在应用中自动配置 Spring 容器中的各个组件,大大简化了开发者的工作。总之,Spring Boot 的自动装配通过条件化配置和默认值,实现了在应用中自动配置 Spring 容器中的各个组件。:每个自动配置类都有一个特定的条件,当条件满足时,自动配置类中定义的 Bean 将被添加到 Spring 容器中。注解是启用自动配置的关键,它会告诉 Spring Boot 自动扫描和加载。

kankan_s的专栏 131

spring cloud-sleuth原理浅析

本文基于sleuth 2.2.5版本 sleuth是一个链路追踪工具,通过它在日志中打印的信息可以分析出一个服务的调用链条,也可以得出链条中每个服务的耗时,这为我们在实际生产中,分析超时服务,分析服务调用关系,做服务治理提供帮助。 第一次使用sleuth,虽说跟着网上的教程也可以运行出正确的结果,但是对于原理、更进一步的使用还是一头蒙。我就尝试着分析一下源代码,其代码量并不大,但是代码还真是难懂,看了一段时间源码,并从网上找了资料,只是对原理、部分类的作用有了一些了解,我通过本文做一下介绍。 文章目.

3060

SpringBoot启动原理以及过程分析

我们启动一个springboot项目,最简单的就是配置一个springboot启动类,然后运行即可 通过上面的代码,我们可以看出springboot启动的关键主要有两个地方,第一个就是@SpringBootApplication注解,第二个就是 SpringApplication.run(SpringBoot.class, args);这个方法下面我们就研究这两个地方都做了什么?@SpringBootApplication上面除了元注解,有三个我们感兴趣的三个注解 @SpringBootConfigurat

qq_2662385590的博客 415

@SpringbootApplication注解的自动装配

@Springbootapplication注解后,在注解内部,spring自动定义了开启事务管理。 查看启动类的组合注解: 上面标红的注解是我们的自动装配的注解:我们进入这个注解的源代码,去查看它的选择器: 这个注解是根据其类中的属性,进行自动装配,我们需要进入其源代码: 找到自动获得的Entry,进入其源代码: (查看调用堆栈,这里是在bean生命周期的invokeBeanFactoryPostProcessors的过程中去扫描注解的步骤) 通过????上面的截图..

qq_34116044的博客 238
上一篇: Java8 Duplicate key 异常解决
下一篇: HTTP Basic Auth:使用和Postman 测试
过河的小卒子
博客等级 码龄10年 39粉丝 112原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值