SpringBoot Starter 自动装配完整原理 + 实战

SpringBoot Starter 自动装配完整原理 + 实战

SpringBoot Starter 自动装配完整原理 + 实战

一、什么是自动装配?

传统 SSM 开发:需要手动 XML/JavaConfig 配置 Bean、导入第三方组件、管理依赖。

SpringBoot 自动装配:引入依赖后,Spring 容器自动识别并注册所需 Bean,业务工程零配置、无需手动 new、无需 @Bean

我们封装自定义 Starter 的核心就是实现自定义自动装配,分为两大核心机制:

  1. SPI 扩展文件META-INF/spring.factories(SpringBoot 2.x 主流方式)
  2. 条件注解(按需装配,不存在对应类 / 配置就不创建 Bean)

二、自动装配底层核心原理

2.1 启动入口:@SpringBootApplication

@SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }

@SpringBootApplication组合注解包含@EnableAutoConfiguration,这是自动装配开关。

2.2 @EnableAutoConfiguration 工作流程

  1. 通过AutoConfigurationImportSelector类读取所有 Jar 包下META-INF/spring.factories
  2. 读取文件中EnableAutoConfiguration对应的配置类全类名列表;
  3. 使用条件注解过滤不满足环境的配置类;
  4. 满足条件的配置类内部通过@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(); } }
常用条件注解说明(自动装配灵魂)
注解作用使用场景
@ConditionalOnClassclasspath 存在指定类才生效依赖 Redis 才装配 Redis 工具
@ConditionalOnMissingBean容器没有该 Bean 才创建允许业务自定义覆盖默认组件
@ConditionalOnPropertyyml 配置匹配才生效总开关控制整套 Starter 启停
@ConditionalOnWebApplicationWeb 环境才装配区分普通工程 / 网关响应式工程
@ConditionalOnResourceclasspath 存在指定文件才加载读取自定义资源文件

步骤 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(关键,缺一不可)

  1. 路径固定:src/main/resources/META-INF/spring.factories
  2. 文件内容格式:key = 值列表,逗号分隔多个配置类
  3. key 固定为:org.springframework.boot.autoconfigure.EnableAutoConfiguration
  4. value 填写我们自定义自动配置类完整全限定名

factories

# 自动装配注册自定义配置类 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.security.starter.config.SecurityAutoConfiguration

原理:SpringBoot 启动时扫描所有 Jar 包的该文件,自动加载右侧配置类,无需业务工程加任何@EnableXXX注解。

四、测试验证自动装配是否生效

4.1 Starter 打包

执行 Maven 命令,将自定义 starter 打包安装到本地仓库

mvn clean install -DskipTests

4.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 注解(手动开启)

  1. 创建注解@EnableSecurityFramework
  2. 注解内部@Import(SecurityAutoConfiguration.class)
  3. 业务启动类添加@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 路径 / 类名写错,装配失效

  1. 目录必须是resources/META-INF,大小写不能错;
  2. 类名必须写完整全限定名,包名、类名不能少;
  3. 换行使用\结尾,不能有多余空格。

坑 2:yml 配置无法注入 Properties

  • 缺少@EnableConfigurationProperties
  • @ConfigurationProperties前缀与 yml 不匹配;
  • 缺少 get/set 方法,无法反射赋值。

坑 3:条件注解不生效,Bean 不该创建却创建

检查注解参数:matchIfMissinghavingValue配置是否正确。

坑 4:引入 starter 后启动报类找不到

Starter pom 依赖 scope 不能设为 provided,必须默认 compile,业务工程才能传递依赖。

八、总结

  1. 自动装配核心入口@EnableAutoConfiguration,通过 SPI 文件spring.factories加载配置类;
  2. 三大核心组成:自动配置类 + 配置属性绑定 + SPI 注册文件;
  3. 条件注解是自动装配的核心,实现按需加载、环境兼容、业务自定义覆盖;
  4. 封装通用 Starter 优先使用 spring.factories 方式,实现引入依赖零配置开箱即用
  5. 完整流程:编写配置类 → 绑定 yml 参数 → 配置 spring.factories → 打包测试。