SpringBoot2.x 教程:自动装配原理与条件注解详解

Spring与SpringBoot:区别、原理与选型全解析 在Java后端技术栈中,IoC容器与依赖注入是理解Spring框架的核心,它解决了对象生命周期管理和解耦问题。而Spring Boot则在Spring之上引入了自动装配与起步依赖机制,将传统繁琐的XML配置转化为约定优于配置的快速开发体验。从手动装配到条件化自动配置的演进,不仅提升了开发效率,也带来了依赖管理、部署形态和微服务化方式的深刻变革。对于开发者而言,理解两者在底层机制、配置方式、启动与部署流程上的差异,有助于在实际项目中做出合理的选型决策,并规避版本升级、依赖冲突等常见风险。基于核心原理与工程实践 阅读详情

spring Boot采用约定优于配置的方式,大量的减少了配置文件的使用。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。
当springboot启动的时候,默认在容器中注入许多AutoCongfigution类。在我们加入spring-boot-stareter-xx时,XXXAutoConfiguration类根据对应的条件,自动选择装配对应的Bean实例注入IOC容器中。

先说结论

  1. SpringBoot启动的时候加载主配置类,开启了自动配置功能@EnableAutoConfiguration
  2. @EnableAutoConfiguration Import的AutoConfigurationImportSelector中代码最终调用SpringFactoriesLoader.loadSpringFactories扫描了Jar包的META-INF/spring.factories文件加载了大量的XXAutoConfiguration类
  3. AutoConfiguration类配合Conditonal注解与ConfigurationProperties配置类在特定条件下自动装配我们需要的Bean到IOC容器中。

注入AutoConfiguration类核心源码分析

SpringBoot的主启动类上需要加入@SpringBootApplication注解,我们看看该注解的源码。

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
	//...省略
}

实际是@EnableAutoConfigurtaion注解起作用。

@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
	String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
	Class<?>[] exclude() default {};
	String[] excludeName() default {};

}

看到@Import注解是不是很熟悉,该注解作用见教程@Enable原理,主要能够导入下面3种情况中的Bean。

  1. 允许注入使用@Configuration注解的类
  2. 允许使用实现ImportSelectorj接口的类,注入selectImports返回的类
  3. 允许是实现了ImportBeanDefinitionRegistrar接口的类

AutoConfigurationImportSelector中selectImports源码

	@Override
	public String[] selectImports(AnnotationMetadata annotationMetadata) {
		if (!isEnabled(annotationMetadata)) {
			return NO_IMPORTS;
		}
		AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
		return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
	}

其中AutoConfigurationImportSelector.getAutoConfigurationEntry调用AutoConfigurationImportSelector.getCandidateConfigurations调用SpringFactoriesLoader.loadFactoryNames调用SpringFactoriesLoader.loadSpringFactories。

其中SpringFactoriesLoader.loadSpringFactories从指定的配置文件META-INF/spring.factories加载配置。

    private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
        MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
        if (result != null) {
            return result;
        } else {
            try {
                Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
                LinkedMultiValueMap result = new LinkedMultiValueMap();

                while(urls.hasMoreElements()) {
                    URL url = (URL)urls.nextElement();
                    UrlResource resource = new UrlResource(url);
                    Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                    Iterator var6 = properties.entrySet().iterator();

                    while(var6.hasNext()) {
                        Entry<?, ?> entry = (Entry)var6.next();
                        String factoryTypeName = ((String)entry.getKey()).trim();
                        String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
                        int var10 = var9.length;

                        for(int var11 = 0; var11 < var10; ++var11) {
                            String factoryImplementationName = var9[var11];
                            result.add(factoryTypeName, factoryImplementationName.trim());
                        }
                    }
                }

                cache.put(classLoader, result);
                return result;
            } catch (IOException var13) {
                throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
            }
        }
    }

总结:

  1. @SpringBootApplication中@EnableAutoConfiguration注解最终调用SpringFactoriesLoader.loadSpringFactories,从classpath中搜寻所有的META-INF/spring.factories配置文件
  2. 并将其中org.springframework.boot.autoconfigure.EnableutoConfiguration对应的配置项通过反射实例化为对应的标注了@Configuration的JavaConfig形式的IoC容器配置类,然后汇总为一个并加载到IoC容器。

条件注解

在spring-boot-autoconfigure包在META-INF/spring.factories文件中autoconfiguration配置项一览。

我们拿DataSourceAutoConfiguration源码分析,看看autoconfiguration类生效的条件。

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@ConditionalOnMissingBean(type = "io.r2dbc.spi.ConnectionFactory")
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class })
public class DataSourceAutoConfiguration {

	@Configuration(proxyBeanMethods = false)
	@Conditional(EmbeddedDatabaseCondition.class)
	@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
	@Import(EmbeddedDataSourceConfiguration.class)
	protected static class EmbeddedDatabaseConfiguration {

	}

	@Configuration(proxyBeanMethods = false)
	@Conditional(PooledDataSourceCondition.class)
	@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
	@Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class,
			DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.Generic.class,
			DataSourceJmxConfiguration.class })
	protected static class PooledDataSourceConfiguration {

	}
	//省略....

}

在DataSourceAutoConfiguration类中,存在大量的@ConditionalXX条件注解,常见条件注解作用:

  1. @ConditionalOnBean:当SpringIoc容器内存在指定Bean的条件
  2. @ConditionalOnClass:当SpringIoc容器内存在指定Class的条件
  3. @ConditionalOnExpression:基于SpEL表达式作为判断条件
  4. @ConditionalOnJava:基于JVM版本作为判断条件
  5. @ConditionalOnJndi:在JNDI存在时查找指定的位置
  6. @ConditionalOnMissingBean:当SpringIoc容器内不存在指定Bean的条件
  7. @ConditionalOnMissingClass:当SpringIoc容器内不存在指定Class的条件
  8. @ConditionalOnNotWebApplication:当前项目不是Web项目的条件
  9. @ConditionalOnProperty:指定的属性是否有指定的值
  10. @ConditionalOnResource:类路径是否有指定的值
  11. @ConditionalOnSingleCandidate:当指定Bean在SpringIoc容器内只有一个,或者虽然有多个但是指定首选的Bean
  12. @ConditionalOnWebApplication:当前项目是Web项目的条件
  13. @EnableConfigurationProperties注解:使使用 @ConfigurationProperties 注解的类生效。
    我们可以看在DataSourceAutoConfiguration激活了DataSourceProperties配置,并且根据条件注解在不同情况下加载不同的数据源到IOC容器中。

千里之行,始于足下。

Spring Data R2DBC API(Spring Data R2DBC 开发文档).CHM Spring Data R2DBC。 官网 Spring Data R2DBC API。 Spring Data R2DBC 开发文档。 立即下载

相关推荐

EB TRESOS 29.0.0安装教程用于MCAL配置开发

本文介绍的搭建基于NXP官网提供EB软件,进行基于标准AUTOSAR软件底层驱动配置的开发

qq_53260940的博客 1877

springboot2.x基础教程:自动装配原理与条件注解源码分析

spring Boot采用约定优于配置的方式,大量的减少了配置文件的使用。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。 当springboot启动的时候,默认在容器中注入许多AutoCongfigution类。在我们加入spring-boot-stareter-xx时,XXXAutoConfiguration类根据对应的条件,自动选择装配对应的Bean实例注入IOC容器中。 先说结论 SpringBoot启动的时候加载主配置类,开启了自动配置功能@EnableAutoCo.

编程之家出品 286

Node-Red系列教程——NodeRed通过OPC UA读取数据并写入mysql

NodeRed通opcua读取西门子数据并存入mysql

鲸鱼姐的专栏 1万+

SpringBoot参数封装问题

SpringBoot参数封装问题参数封装原因参数封装过程最终解决方案注意事项 参数封装 原因 最近在重构项目,需要对树接口进行重构,原先是通过字符串拼接,使用HttpClient客户端进行调用,现需改成openFeign客户端调用,因此,需要把有关树的参数封装为DTO的形式,方便调用。 参数封装过程 参数需要: http:/ip:port/tree?query[form]=xxx&query[userId]=xxx&page.sort[0].field=SHOW_ORDER&page

weixin_45785469的博客 723

【ARM Trace32(劳特巴赫) 使用介绍 10 -- Trace32 scan dump 详细介绍】

将图 1-2 中扫描单元按照扫描移位模式连接起来,就构成了扫描测试中的基本结构,这里介绍下全扫描。全扫描就是多个扫描单元相连接,上一单元的扫描输出,连接到目前单元的扫描输入,目前单元的扫描输出连接到下一单元的扫描输入,以此类推,构成一条移位寄存器链,如图1-3 所示:图 1-3 全扫描这样的扫描结构,可通过一个串行输入端,将期望的数据存入移位寄存器链并观察运行结果。

CodingCos的博客 2033

c#视觉应用开发中如何使用Emgu CV在C#中进行图像处理?

Emgu CV 是 OpenCV 的 .NET 包装器,可以让开发者在 .NET 语言(如 C#)中使用 OpenCV 的功能进行图像处理。在进行图像处理时,Emgu CV 提供了丰富的 API 可以使用。PictureBoxImageBox下面是一个详细的示例,演示如何使用 Emgu CV 在 C# 中进行基本的图像处理,包括加载图像、转换为灰度图像、进行边缘检测,然后显示结果。byte在这个示例中,我们使用了三个PictureBox控件来显示原始图像、灰度图像和边缘检测后的图像。

zhangzhechun的专栏 670

r2dbc介绍 及 动态数据源实现方式

一、基本概念: 传统情况Java 使用 JDBC 来操作关系型数据库,而 JDBC 是阻塞的、同步的,即使使用线程池进行改善也是有限的。基于此,Spring官方(Pivotal)提出了R2DBC(Reactive Relational Database Connectivity)。R2DBC是一项API规范计划,它声明了一个反应式API,该方法将由数据库厂商实现以访问其关系数据库。 目前实现了R2DBC的数据库驱动有:H2、MariaDB、Microsoft SQL Server、MySQL 、jasy

wangqiso的博客 1万+

【示波器专题】示波器探头的原理深入——有源探头之差分有源探头

差分有源探头是一种特殊的有源探头,与普通单端有源探头的区别在于其前端的放大器是差分放大器。差分放大器的好处是可以直接测试高速差分信号,同时其共模抑制比高,对共模噪声的抑制能力比较好。...

一点硬件 2625

SpringBoot 官方文档示例:(68)使用R2DBC操作Postgresql

boot

amadeus_liu2的博客 2402

[系统安全] 三十二.恶意代码检测(2)常用技术详解及总结

前文从产业界和学术界分别详细讲解恶意代码攻击溯源的相关知识,在学术界方面,用类似于综述来介绍攻击追踪溯源的不同方法;在产业界方面,主要参考李东宏老师从企业恶意样本分析的角度介绍溯源工作。这篇文章将详细总结恶意代码检测技术,包括恶意代码检测的对象和策略、特征值检测技术、校验和检测技术、启发式扫描技术、虚拟机检测技术和主动防御技术。希望这篇文章对您有所帮助,如果文章中存在错误、理解不到位或侵权的地方,还请告知作者与海涵。且看且珍惜,加油~

杨秀璋的专栏 1万+

Qt 【window udp 高频采集丢包问题】

使用Asio + 无锁队列或者环形缓存区方案可以解决 qt udp 在window平台高速采集 (128k)丢包问题。

weixin_45397344的博客 177

SpringBoot数据源——为什么平时默认线程池是Hikari

为什么平时默认线程池是Hikari?点开类,带你解读

运气不好努力来凑 1855

【用unity实现100个游戏之15】开发一个类保卫萝卜的Unity2D塔防游戏5(附项目源码,完结)

本期是本项目的最后一篇,主要内容是配置环境、生成不同敌人、结束重开。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 2575

spring boot 注解_springboot2x基础教程:自动装配原理与条件注解

spring Boot采用约定优于配置的方式,大量的减少了配置文件的使用。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。当springboot启动的时候,默认在容器中注入许多AutoCongfigution类。在我们加入spring-boot-stareter-xx时,XXXAutoConfiguration类根据对应的条件,自动选择装配对应的...

weixin_39559015的博客 104

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

SpringBoot Starter开发指南:原理与实践

SpringBoot Starter是Spring框架中实现自动配置的核心机制,它基于约定优于配置的原则,通过预定义的依赖管理和自动装配逻辑,显著简化了Java应用的开发流程。其技术原理主要依赖于条件注解(如@ConditionalOnClass)和配置属性绑定,使得开发者只需引入starter依赖即可获得开箱即用的功能模块。在企业级开发中,自定义starter能够封装通用技术组件(如MyBatis、Redis等),实现配置标准化和依赖管理。通过合理设计自动配置类和模块化拆分,可以避免循环依赖和版本冲突问题

weixin_29306875的博客 237

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

深入理解 SpringBoot 自动装配机制:基于 Conditional 条件注解与 AutoConfiguration 的解析

我写这篇文章的主要读者,是正在学习 SpringBoot 内核机制、想真正搞懂“自动装配到底是怎么实现的”的 Java 开发者。 我最近在重构一个内部服务时,为了定制自己的 Starter,需要深入理解 SpringBoot 自动装配的执行链路,因此把我的理解过程整理下来,方便新手快速避坑,也方便有经验的开发者查阅。本文不会展示过多无关图片或段子,只使用必要的结构辅助,保持阅读效率。SpringBoot 的自动装配并不是黑盒,它非常工程化:这两个机制协作,决定哪些 Bean 最终会被加入 Spring 容器

聚焦学生开发者需求,分享课设毕设项目实战经验、系统开发技巧、数据库设计规范及文档排版实用方法。 685

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

SpringBoot系列04:SpringBoot Starter 深度解析:从自动装配原理到企业级自定义组件封装实战

SpringBoot Starter深度解析与实战摘要 本文深入剖析SpringBoot Starter机制,解决开发者"只会用不懂原理"的痛点。

深耕 Java 后端与企业级软件架构设计,专注微服务、分布式系统、大模型 AI 应用架构落地。 473

SpringBoot自动装配原理与实战排查:从条件注解到自定义starter

Spring Boot作为Java后端开发的主流框架,其自动装配机制极大简化了项目配置。自动装配的核心是基于条件注解的智能判断,通过AutoConfigurationImportSelector加载候选配置类,并结合@ConditionalOnClass、@ConditionalOnMissingBean等注解实现按需装配。这一设计将“约定优于配置”落地为可执行的规则,有效减少了重复样板代码,提升了多模块项目的维护效率。当引入依赖或自定义starter时,自动装配能自动识别类路径与属性配置,快速构建数据源、

weixin_29212429的博客 146

SpringBoot 2.x/3.x自动装配原理与实战:从入门到独立开发

在Java后端开发中,SpringBoot以其“约定优于配置”的设计理念,大幅降低了企业级应用的构建门槛。其核心机制自动装配,通过条件注解按需加载Bean,让开发者无需手写繁琐的XML配置即可快速启动项目。理解从@EnableAutoConfiguration到AutoConfigurationImportSelector的工作原理,不仅能解决框架升级时的兼容性问题,还能为自定义Starter、微服务治理打下坚实基础。无论你是正从SpringMVC迁移的老手,还是刚接触MCP、AI工具集成的新人,掌握Spr

weixin_33600816的博客 205

告别繁琐配置:SpringBoot自动配置原理浅析

SpringApplication.run()启动时,会调用getSpringFactoriesInstances()方法,扫描所有META-INF/spring.factories文件,实例化所有AutoConfigurationImportFilter和AutoConfigurationImportSelector。这是排查问题的最强武器。它没有消灭配置,而是把配置的“决策”和“执行”分离,让开发者只用关心决策(编写业务逻辑和少量配置项),而让框架完成冗长的执行过程(初始化Bean、设置依赖)。

2501_90410679的博客 18

SpringBoot自动装配与启动流程全解:从原理到多数据源与版本升级

SpringBoot作为Java后端开发的脚手架,通过起步依赖和自动配置大幅简化了项目搭建。理解其自动装配机制,需要从@SpringBootApplication组合注解、条件注解与AutoConfiguration.imports入手,掌握配置生效与失效的排查方法。同时,SpringApplication.run()背后的启动流程、配置文件优先级与多环境切换,也是定位运行时问题的关键。在实际工程中,多数据源配置、Redis等中间件整合、拦截器与过滤器的使用,以及SpringBoot 2.x向3.x升级时的

weixin_33483304的博客 105

SpringBoot自定义Starter

Starter(场景启动器)是SpringBoot为场景化自动装配设计的依赖封装组件,核心作用:整合场景所需依赖、自动加载配置类、初始化核心Bean,开发者只需引入依赖,无需手动配置即可使用对应功能。Starter = 依赖聚合 + 自动配置 + 场景能力封装,彻底告别传统SSM的繁琐配置。项目通用工具能力封装:统一日志、统一异常处理、接口加密解密通用业务组件复用:分页封装、字典转换、权限校验、限流熔断第三方工具适配:自定义SDK整合、中间件二次封装团队统一规范:统一配置、统一返回体、全局拦截器。

只要肯攀登,终有登顶时 332

SpringBoot惊艳功能盘点:自动装配、事件驱动与生产监控

在Java后端开发中,配置管理、代码解耦与工程效率始终是实践中的核心痛点。SpringBoot以“约定大于配置”的设计思想,通过自动装配机制和条件注解,让依赖管理与Bean装配变得高度自动化,大幅减少了样板代码。借助@ConfigurationProperties实现类型安全的配置绑定,结合@EventListener事件驱动与@Async异步任务,业务逻辑得以清晰解耦;拦截器与自定义注解能优雅解决登录鉴权等横切关注点,分页插件的合理选型则让数据查询更高效。面对生产环境,Profile多环境配置与Actua

weixin_34221654的博客 237

解密Spring Boot:揭秘自动装配背后的原理与机制

《解密Spring Boot:揭秘自动装配背后的原理与机制》是深入探讨Spring Boot框架内部工作原理。它详细解释了Spring Boot如何实现自动装配,并揭示了其背后的原理和机制。通过分析Spring Boot的源代码和核心组件,读者将了解到Spring Boot是如何通过自动装配实现简化开发、提高效率的。这本书提供了对Spring Boot自动装配的全面理解,为开发人员提供了更深入的洞察力,帮助他们更好地利用Spring Boot框架开发高效、可靠的应用程序。

忆~遂愿的博客 3961

Springboot2.0.X自动装配原理自动装配原理

1.Springboot2.0.X自动装配原理自动装配原理a.Springboot如何自动装配: 以HttpEncodingAutoConfiguration通过源码为例; 1.@Configuration:标识此类为配置类,将此类纳入SpringIOC容器; 2. @EnableConfigurationProperties(value=HttpEncodingPro...

wangtao的博客 2938

SpringBoot自动装配详解

Spring Boot 的自动装配(Auto-Configuration)原理是基于Spring Framework的条件化配置和注解实现的。这种机制允许开发者在项目中引入相关的依赖,Spring Boot 将根据这些依赖自动配置应用程序的上下文和功能。SpringBoot 定义了一套接口规范,这套规范规定:SpringBoot 在启动时会扫描外部引用 jar 包中的。

goat的博客 2984
上一篇: 准备一个多月,三战腾讯!分享复习经验和后台开发面经(附赠复习资料)
下一篇: 阿里P8高级技术专家强烈推荐:2020Java程序员进阶必读书单(附赠电子档)
「已注销」
博客等级 码龄6年 36粉丝 149原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值