SpringBoot Starter 自动装配完整原理 + 实战
一、什么是自动装配?
传统 SSM 开发:需要手动 XML/JavaConfig 配置 Bean、导入第三方组件、管理依赖。
SpringBoot 自动装配:引入依赖后,Spring 容器自动识别并注册所需 Bean,业务工程零配置、无需手动 new、无需 @Bean。
我们封装自定义 Starter 的核心就是实现自定义自动装配,分为两大核心机制:
- SPI 扩展文件
META-INF/spring.factories(SpringBoot 2.x 主流方式) - 条件注解(按需装配,不存在对应类 / 配置就不创建 Bean)
二、自动装配底层核心原理
2.1 启动入口:@SpringBootApplication
@SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }@SpringBootApplication组合注解包含@EnableAutoConfiguration,这是自动装配开关。
2.2 @EnableAutoConfiguration 工作流程
- 通过
AutoConfigurationImportSelector类读取所有 Jar 包下META-INF/spring.factories; - 读取文件中
EnableAutoConfiguration对应的配置类全类名列表; - 使用条件注解过滤不满足环境的配置类;
- 满足条件的配置类内部通过
@Bean注册组件到 Spring 容器。
2.3 完整流程图
引入 starter 依赖 → 加载 spring.factories → 读取自定义自动配置类 → 条件注解判断环境 → 注册工具类、切面、过滤器等 Bean。
三、实现自动装配三步走(实战,基于限流幂等 Starter)
步骤 1:编写自动配置类(核心配置类)
作用:统一声明需要交给 Spring 管理的 Bean,配合条件注解实现按需加载。
package com.security.starter.config; import com.security.starter.aop.IdempotentAspect; import com.security.starter.core.IdempotentUtil; import com.security.starter.prop.SecurityProperties; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; /** * 自定义自动装配主配置类 */ @Configuration // 开启yml配置属性绑定,把配置注入SecurityProperties @EnableConfigurationProperties(SecurityProperties.class) // 条件注解:yml中 security.framework.enable=true 才加载整套组件,不配置默认开启 @ConditionalOnProperty( prefix = "security.framework", name = "enable", havingValue = "true", matchIfMissing = true ) // 导入子配置:Sentinel Nacos持久化配置 @Import(SentinelNacosAutoConfig.class) public class SecurityAutoConfiguration { /** * 注册幂等工具类 * ConditionalOnMissingBean:业务工程如果自己注入了IdempotentUtil,则优先使用业务自定义Bean */ @Bean @ConditionalOnMissingBean public IdempotentUtil idempotentUtil() { return new IdempotentUtil(); } /** * 注册幂等AOP切面 */ @Bean @ConditionalOnMissingBean public IdempotentAspect idempotentAspect() { return new IdempotentAspect(); } }常用条件注解说明(自动装配灵魂)
| 注解 | 作用 | 使用场景 |
|---|---|---|
@ConditionalOnClass | classpath 存在指定类才生效 | 依赖 Redis 才装配 Redis 工具 |
@ConditionalOnMissingBean | 容器没有该 Bean 才创建 | 允许业务自定义覆盖默认组件 |
@ConditionalOnProperty | yml 配置匹配才生效 | 总开关控制整套 Starter 启停 |
@ConditionalOnWebApplication | Web 环境才装配 | 区分普通工程 / 网关响应式工程 |
@ConditionalOnResource | classpath 存在指定文件才加载 | 读取自定义资源文件 |
步骤 2:配置属性绑定类(读取 yml 自定义参数)
通过@ConfigurationProperties绑定 yml 配置,@EnableConfigurationProperties在配置类开启绑定。
package com.security.starter.prop; import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix = "security.framework") public class SecurityProperties { private boolean enable = true; private String idempotentPrefix = "idempotent:token:"; private String nacosGroup = "SENTINEL_GROUP"; // getter、setter }步骤 3:创建 SPI 文件 spring.factories(关键,缺一不可)
- 路径固定:
src/main/resources/META-INF/spring.factories - 文件内容格式:key = 值列表,逗号分隔多个配置类
- key 固定为:
org.springframework.boot.autoconfigure.EnableAutoConfiguration - value 填写我们自定义自动配置类完整全限定名
factories
# 自动装配注册自定义配置类 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.security.starter.config.SecurityAutoConfiguration原理:SpringBoot 启动时扫描所有 Jar 包的该文件,自动加载右侧配置类,无需业务工程加任何
@EnableXXX注解。
四、测试验证自动装配是否生效
4.1 Starter 打包
执行 Maven 命令,将自定义 starter 打包安装到本地仓库
mvn clean install -DskipTests4.2 业务工程引入依赖
<dependency> <groupId>com.security</groupId> <artifactId>security-spring-boot-starter</artifactId> <version>1.0.0</version> </dependency>4.3 测试注入
直接在 Controller 注入工具类,不需要任何配置,能正常注入即代表自动装配成功:
@RestController public class TestController { // 自动装配生效,直接注入 @Resource private IdempotentUtil idempotentUtil; @GetMapping("/test") public Result<String> test() { String token = idempotentUtil.generateToken(600); return Result.success(token); } }4.4 开关测试
在 yml 关闭组件,验证 Bean 不再注入
security: framework: enable: false启动项目,注入IdempotentUtil会报No qualifying bean,说明条件注解生效。
五、两种自动装配模式对比
模式 1:spring.factories 自动装配(推荐,本文方案)
- 优点:业务项目无需添加任何启动注解,引入依赖即生效,开箱即用;
- 适用:通用基础组件、封装 Starter、中间件集成。
模式 2:自定义 @EnableXXX 注解(手动开启)
- 创建注解
@EnableSecurityFramework; - 注解内部
@Import(SecurityAutoConfiguration.class); - 业务启动类添加
@EnableSecurityFramework才会加载配置;
- 优点:可控性强,需要手动显式开启;
- 缺点:多一行代码,自动化程度低;
- 适用:可选扩展组件、复杂业务模块。
示例:手动开启模式
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Import(SecurityAutoConfiguration.class) public @interface EnableSecurityFramework { }业务启动类使用:
@SpringBootApplication @EnableSecurityFramework public class OrderApplication { }六、企业级进阶优化点
6.1 兼容存在 Redis 才装配幂等工具
增加@ConditionalOnClass(RedisTemplate.class),无 Redis 依赖时不创建 Bean,避免启动报错
@Bean @ConditionalOnClass(RedisTemplate.class) @ConditionalOnMissingBean public IdempotentUtil idempotentUtil() { return new IdempotentUtil(); }6.2 支持业务自定义覆盖默认组件
全部@Bean增加@ConditionalOnMissingBean,业务项目自己定义同名 Bean 时,会覆盖 Starter 内部默认实现,扩展灵活。
6.3 配置元数据,IDE 自动提示
引入配置处理器依赖,自动生成配置提示文件,编写 yml 时有提示:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-configuration-processor</artifactId> <optional>true</optional> </dependency>6.4 拆分多配置类,模块化管理
Sentinel 配置独立
SentinelNacosAutoConfig;幂等核心配置
SecurityAutoConfiguration使用
@Import导入,解耦代码,便于维护。
七、常见自动装配踩坑
坑 1:spring.factories 路径 / 类名写错,装配失效
- 目录必须是
resources/META-INF,大小写不能错; - 类名必须写完整全限定名,包名、类名不能少;
- 换行使用
\结尾,不能有多余空格。
坑 2:yml 配置无法注入 Properties
- 缺少
@EnableConfigurationProperties; @ConfigurationProperties前缀与 yml 不匹配;- 缺少 get/set 方法,无法反射赋值。
坑 3:条件注解不生效,Bean 不该创建却创建
检查注解参数:matchIfMissing、havingValue配置是否正确。
坑 4:引入 starter 后启动报类找不到
Starter pom 依赖 scope 不能设为 provided,必须默认 compile,业务工程才能传递依赖。
八、总结
- 自动装配核心入口
@EnableAutoConfiguration,通过 SPI 文件spring.factories加载配置类; - 三大核心组成:自动配置类 + 配置属性绑定 + SPI 注册文件;
- 条件注解是自动装配的核心,实现按需加载、环境兼容、业务自定义覆盖;
- 封装通用 Starter 优先使用 spring.factories 方式,实现引入依赖零配置开箱即用;
- 完整流程:编写配置类 → 绑定 yml 参数 → 配置 spring.factories → 打包测试。