自定义 Spring Boot 自动配置

目录

一、核心前提与设计原则

[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),方便其他项目引入:

  1. 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>
  1. 执行 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、超时时间等,说明自动配置生效;
  • 若自定义 SmsTemplate Bean,自动配置的 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)会自动提示配置属性,无需手动记忆。

五、自定义自动配置的核心注意事项

  1. 类路径隔离:确保自动配置类的依赖不会冲突(如避免引入多余的 Spring 版本);
  2. 条件注解精准:避免条件过松导致不必要的 Bean 初始化,或过紧导致配置不生效;
  3. 配置校验:对必选配置(如 access-key)做校验,抛出明确异常,方便用户排查;
  4. 兼容性:注意 Spring Boot 版本差异(如 2.7+ 配置文件路径变化);
  5. 文档完善:标注配置属性的含义、默认值、必填项,降低使用成本。

六、总结

自定义 Spring Boot 自动配置的核心流程可总结为:

plaintext

复制代码
定义配置属性类(@ConfigurationProperties)→ 
编写核心业务类 → 
编写自动配置类(@Configuration + 条件注解 + @Bean)→ 
注册自动配置类(AutoConfiguration.imports)→ 
打包为 Starter → 
其他项目引入并使用

其底层完全复用 Spring Boot 内置自动配置的逻辑:通过 @EnableAutoConfiguration 加载配置类,通过条件注解控制生效时机,通过 @ConditionalOnMissingBean 保证用户配置优先。掌握这一流程,可将任意通用功能封装为自动配置组件,大幅提升开发效率。

相关推荐
愿你天黑有灯下雨有伞2 小时前
Spring Boot 使用FastExcel实现多级表头动态数据填充导出
java·faseexcel
是席木木啊2 小时前
Spring Boot 中 @Async 与 @Transactional 结合使用全解析:避坑指南
数据库·spring boot·oracle
CodeAmaz2 小时前
Spring编程式事务详解
java·数据库·spring
没有bug.的程序员2 小时前
微服务基础设施清单:必须、应该、可以、无需的四级分类指南
java·jvm·微服务·云原生·容器·架构
武子康2 小时前
Java-204 RabbitMQ Connection/Channel 工作流程:AMQP 发布消费、抓包帧结构与常见坑
java·分布式·消息队列·rabbitmq·ruby·java-activemq
郑州光合科技余经理2 小时前
海外国际版同城服务系统开发:PHP技术栈
java·大数据·开发语言·前端·人工智能·架构·php
appearappear2 小时前
Mac 上重新安装了Cursor 2.2.30,重新配置 springboot 过程记录
java·spring boot·后端
CryptoRzz2 小时前
日本股票 API 对接实战指南(实时行情与 IPO 专题)
java·开发语言·python·区块链·maven
程序员水自流2 小时前
MySQL数据库自带系统数据库功能介绍
java·数据库·mysql·oracle