目录
[1. 核心依赖](#1. 核心依赖)
[2. 设计原则](#2. 设计原则)
[二、自定义自动配置的完整步骤(实战:自定义短信 Starter)](#二、自定义自动配置的完整步骤(实战:自定义短信 Starter))
[步骤 1:定义配置属性类(绑定配置文件)](#步骤 1:定义配置属性类(绑定配置文件))
[步骤 2:定义核心业务类(自动配置的目标 Bean)](#步骤 2:定义核心业务类(自动配置的目标 Bean))
[步骤 3:编写自动配置类(核心逻辑)](#步骤 3:编写自动配置类(核心逻辑))
[步骤 4:注册自动配置类(关键:让 Spring Boot 发现)](#步骤 4:注册自动配置类(关键:让 Spring Boot 发现))
[步骤 5:打包为 Starter(可选,推荐)](#步骤 5:打包为 Starter(可选,推荐))
[1. 引入 Starter 依赖](#1. 引入 Starter 依赖)
[2. 配置属性(application.yml)](#2. 配置属性(application.yml))
[3. 使用自动配置的 Bean](#3. 使用自动配置的 Bean)
[4. 验证效果](#4. 验证效果)
[1. 多条件组合](#1. 多条件组合)
[2. 自定义 Condition 注解](#2. 自定义 Condition 注解)
[3. 自动配置类排序](#3. 自动配置类排序)
[4. 禁用自动配置](#4. 禁用自动配置)
[5. 配置属性提示(增强开发体验)](#5. 配置属性提示(增强开发体验))
自定义 Spring Boot 自动配置的核心目标是:让第三方组件 / 自研功能像 Spring Boot 内置组件一样,实现「引入依赖即生效、配置可定制、默认可覆盖」。其底层遵循 Spring Boot 自动配置的核心逻辑(条件注解 + 配置属性 + 自动配置类注册),完整流程可拆解为「环境准备 → 核心编码 → 配置注册 → 测试验证」四步,以下是详细实战步骤。
一、核心前提与设计原则
1. 核心依赖
自定义自动配置需引入 Spring Boot 自动配置的基础依赖(建议作为父工程或依赖管理):
xml
<!-- pom.xml 核心依赖 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/>
</parent>
<!-- 自动配置核心依赖(必须) -->
<dependencies>
<!-- Spring Boot 自动配置基础 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<!-- 配置属性绑定注解处理器(可选,用于编译期检查配置属性) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- 测试依赖(可选) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
2. 设计原则
- 约定优于配置:提供合理默认值,无需配置即可使用;
- 条件生效 :通过
@Conditional注解控制自动配置生效时机; - 可覆盖:允许用户通过自定义 Bean / 配置属性覆盖默认行为;
- 可禁用 :提供开关(如
xxx.enabled=false)关闭自动配置。
二、自定义自动配置的完整步骤(实战:自定义短信 Starter)
以「自定义短信发送组件的自动配置」为例,实现:引入依赖后自动初始化短信发送 Bean,支持配置自定义密钥 / 超时时间,支持用户自定义 Bean 覆盖默认实现。
步骤 1:定义配置属性类(绑定配置文件)
作用:将 application.yml 中的自定义配置(如 sms.access-key)绑定到 Java 类,提供类型安全的配置读取。
java
运行
package com.example.sms.autoconfigure;
import org.springframework.boot.context.properties.ConfigurationProperties;
// 配置属性前缀:sms
@ConfigurationProperties(prefix = "sms")
public class SmsProperties {
// 默认开关:开启自动配置
private boolean enabled = true;
// 短信平台接入密钥(默认空,需用户配置)
private String accessKey;
// 短信平台秘钥(默认空,需用户配置)
private String secretKey;
// 请求超时时间(默认 5000ms)
private int timeout = 5000;
// 短信签名(默认空)
private String signName;
// 生成 getter/setter(必须,否则无法绑定配置)
public boolean isEnabled() { return enabled; }
public void setEnabled(boolean enabled) { this.enabled = enabled; }
public String getAccessKey() { return accessKey; }
public void setAccessKey(String accessKey) { this.accessKey = accessKey; }
public String getSecretKey() { return secretKey; }
public void setSecretKey(String secretKey) { this.secretKey = secretKey; }
public int getTimeout() { return timeout; }
public void setTimeout(int timeout) { this.timeout = timeout; }
public String getSignName() { return signName; }
public void setSignName(String signName) { this.signName = signName; }
}
步骤 2:定义核心业务类(自动配置的目标 Bean)
作用:实现短信发送的核心逻辑,作为自动配置要初始化的 Bean。
java
运行
package com.example.sms.autoconfigure;
// 短信发送核心类
public class SmsTemplate {
// 依赖配置属性
private SmsProperties properties;
// 构造注入配置
public SmsTemplate(SmsProperties properties) {
this.properties = properties;
}
// 核心方法:发送短信
public boolean sendSms(String phone, String content) {
// 模拟发送逻辑(实际需调用短信平台 API)
System.out.println("发送短信:");
System.out.println("AccessKey: " + properties.getAccessKey());
System.out.println("Phone: " + phone + ", Content: " + content);
System.out.println("Timeout: " + properties.getTimeout() + "ms");
return true;
}
}
步骤 3:编写自动配置类(核心逻辑)
作用:通过条件注解控制 Bean 的初始化,实现「按需生效、可覆盖」。
java
运行
package com.example.sms.autoconfigure;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
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;
// 标记为配置类
@Configuration
// 开启配置属性绑定(关联 SmsProperties)
@EnableConfigurationProperties(SmsProperties.class)
// 条件1:类路径中存在 SmsTemplate 时生效(保证依赖存在)
@ConditionalOnClass(SmsTemplate.class)
// 条件2:配置属性 sms.enabled=true 时生效(默认开启)
@ConditionalOnProperty(prefix = "sms", name = "enabled", havingValue = "true", matchIfMissing = true)
public class SmsAutoConfiguration {
// 初始化 SmsTemplate Bean
@Bean
// 条件3:容器中不存在 SmsTemplate Bean 时才初始化(允许用户自定义覆盖)
@ConditionalOnMissingBean(SmsTemplate.class)
public SmsTemplate smsTemplate(SmsProperties properties) {
// 校验必要配置(可选,增强健壮性)
if (properties.getAccessKey() == null || properties.getSecretKey() == null) {
throw new IllegalArgumentException("请配置 sms.access-key 和 sms.secret-key!");
}
return new SmsTemplate(properties);
}
}
步骤 4:注册自动配置类(关键:让 Spring Boot 发现)
Spring Boot 需通过特定文件扫描到自定义的自动配置类,需在 src/main/resources 下创建以下目录和文件:
plaintext
src/main/resources/
└── META-INF/
└── spring/
└── org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件内容:写入自动配置类的全限定名(Spring Boot 2.7+ 版本):
plaintext
com.example.sms.autoconfigure.SmsAutoConfiguration
注意:Spring Boot 2.7 之前的版本需在
META-INF/spring.factories中配置:plaintext
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.example.sms.autoconfigure.SmsAutoConfiguration
步骤 5:打包为 Starter(可选,推荐)
将上述代码打包为 Maven/Gradle 依赖(Starter),方便其他项目引入:
- 在
pom.xml中配置打包信息:
xml
<artifactId>sms-spring-boot-starter</artifactId>
<name>sms-spring-boot-starter</name>
<version>1.0.0</version>
<!-- Starter 规范:命名建议为 xxx-spring-boot-starter -->
<dependencies>
<!-- 包含上述自动配置代码的依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
- 执行
mvn clean install安装到本地仓库。
三、使用自定义自动配置(测试验证)
1. 引入 Starter 依赖
在另一个 Spring Boot 项目的 pom.xml 中引入自定义 Starter:
xml
<dependency>
<groupId>com.example</groupId>
<artifactId>sms-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
2. 配置属性(application.yml)
yaml
# 短信配置
sms:
access-key: your-access-key # 必配
secret-key: your-secret-key # 必配
timeout: 3000 # 覆盖默认 5000ms
sign-name: 我的短信签名 # 自定义属性
# enabled: true # 默认开启,可省略
3. 使用自动配置的 Bean
java
运行
package com.example.demo;
import com.example.sms.autoconfigure.SmsTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class DemoApplication {
// 自动注入自定义的 SmsTemplate
@Autowired
private SmsTemplate smsTemplate;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
// 测试接口:发送短信
@GetMapping("/send-sms")
public String sendSms() {
boolean result = smsTemplate.sendSms("13800138000", "您的验证码是 123456");
return result ? "发送成功" : "发送失败";
}
}
4. 验证效果
- 启动项目,访问
http://localhost:8080/send-sms; - 控制台输出配置的 AccessKey、超时时间等,说明自动配置生效;
- 若自定义
SmsTemplateBean,自动配置的 Bean 会被覆盖(验证@ConditionalOnMissingBean)。
四、自定义自动配置的进阶技巧
1. 多条件组合
可通过多个 @Conditional 注解组合控制生效时机,例如:
java
运行
// 仅当是 Web 应用且配置了 sms.web-enabled=true 时生效
@ConditionalOnWebApplication
@ConditionalOnProperty(prefix = "sms", name = "web-enabled", havingValue = "true")
2. 自定义 Condition 注解
若内置条件注解不满足需求,可自定义条件:
java
运行
// 自定义条件:仅当指定短信平台地址存在时生效
public class SmsPlatformUrlCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment env = context.getEnvironment();
return env.containsProperty("sms.platform-url");
}
}
// 使用自定义条件
@Conditional(SmsPlatformUrlCondition.class)
3. 自动配置类排序
通过 @AutoConfigureAfter/@AutoConfigureBefore 控制配置类执行顺序:
java
运行
// 确保在数据源配置之后执行
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class SmsAutoConfiguration {
// ...
}
4. 禁用自动配置
用户可通过以下方式禁用自定义自动配置:
java
运行
// 方式1:排除自动配置类
@SpringBootApplication(exclude = SmsAutoConfiguration.class)
// 方式2:配置属性关闭
sms:
enabled: false
5. 配置属性提示(增强开发体验)
添加 spring-boot-configuration-processor 依赖后,IDE(如 IDEA)会自动提示配置属性,无需手动记忆。
五、自定义自动配置的核心注意事项
- 类路径隔离:确保自动配置类的依赖不会冲突(如避免引入多余的 Spring 版本);
- 条件注解精准:避免条件过松导致不必要的 Bean 初始化,或过紧导致配置不生效;
- 配置校验:对必选配置(如 access-key)做校验,抛出明确异常,方便用户排查;
- 兼容性:注意 Spring Boot 版本差异(如 2.7+ 配置文件路径变化);
- 文档完善:标注配置属性的含义、默认值、必填项,降低使用成本。
六、总结
自定义 Spring Boot 自动配置的核心流程可总结为:
plaintext
定义配置属性类(@ConfigurationProperties)→
编写核心业务类 →
编写自动配置类(@Configuration + 条件注解 + @Bean)→
注册自动配置类(AutoConfiguration.imports)→
打包为 Starter →
其他项目引入并使用
其底层完全复用 Spring Boot 内置自动配置的逻辑:通过 @EnableAutoConfiguration 加载配置类,通过条件注解控制生效时机,通过 @ConditionalOnMissingBean 保证用户配置优先。掌握这一流程,可将任意通用功能封装为自动配置组件,大幅提升开发效率。