不灭的焱

革命尚未成功,同志仍须努力 下载Java21

作者:AlbertWen  添加时间:2026-05-31 11:10:04  修改时间:2026-06-04 09:00:08  分类:07.Java框架/系统  编辑

下面可以先记一句话:

Config 是“配置项/配置文件/配置代码”的简称;Configure 是“去配置”这个动作;Configuration 是“配置体系、配置结果,或 Spring 里的配置类”。

在 Spring Boot 里,它们经常同时出现:

application.yml        -> config 文件 / configuration data
PaymentProperties     -> configuration properties,把 config 绑定成 Java 对象
PaymentConfig         -> configuration class,声明 Bean
@Bean 方法内部          -> configure 某个对象
Spring 容器启动后       -> 形成最终 runtime configuration

1. 三个词的区别

词性 中文理解 在 Spring Boot 中常见位置
config 名词/简称 配置、配置文件、配置项,偏口语和工程命名 application.yml、application.properties、config/ 包、RedisConfig 类名
configure 动词 配置某个东西,强调“动作” configureMessageConverters、addCorsMappings、http.authorizeHttpRequests(...)
configuration 名词 配置整体、配置结果、配置类,偏正式 @Configuration、@ConfigurationProperties、AutoConfiguration

注意:Config 通常只是项目里的命名习惯,不是 Spring Boot 的魔法关键字。比如 RedisConfig 这个类名本身不会让 Spring 识别它;真正让它生效的是 @Configuration、@Component、@Bean、@SpringBootApplication 等注解。Spring 官方文档把 @Configuration 定义为“Bean 定义的来源”,并且通常通过 @Bean 方法声明 Bean;@Bean 方法则负责实例化、配置和初始化交给 Spring IoC 容器管理的对象。(Home)

2. 在 Spring Boot 里怎么对应?

2.1 Config:配置数据,通常放在外部文件里

Spring Boot 支持把配置外置化,这样同一套代码可以运行在开发、测试、生产等不同环境;配置来源可以是 properties 文件、YAML 文件、环境变量、命令行参数等。(Home) 官方也说明,常见应用属性可以写在 application.properties、application.yaml 或命令行参数里。(Home)

例如:

# application.yml
payment:
  gateway:
    base-url: "https://pay.example.com"
    api-key: "${PAYMENT_API_KEY}"
    connect-timeout: 2s
    read-timeout: 5s

这里的 payment.gateway.* 就是 config,也可以说是 application configuration data。

2.2 Configuration:配置类,负责把配置变成 Spring Bean

@Configuration 是 Spring 里的正式概念。它表示这个类是 Bean 定义的来源,里面通常写 @Bean 方法。(Home)

@Configuration
public class PaymentConfig {

    @Bean
    public PaymentClient paymentClient(PaymentProperties props) {
        PaymentClient client = new PaymentClient();
        client.setBaseUrl(props.baseUrl());
        client.setApiKey(props.apiKey());
        client.setConnectTimeout(props.connectTimeout());
        client.setReadTimeout(props.readTimeout());
        return client;
    }
}

这里:

PaymentConfig        -> configuration class,配置类
paymentClient(...)   -> 定义一个 Bean
setBaseUrl(...) 等   -> configure 这个客户端对象

2.3 Configure:配置动作,通常发生在方法内部

configure 是动词,所以它通常不是一个“东西”,而是“正在配置某个东西”。

例如:

client.setBaseUrl(props.baseUrl());
client.setApiKey(props.apiKey());

这两行代码就是在 configure PaymentClient

再比如 Spring MVC 里的 CORS 配置:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedOrigins("https://admin.example.com")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowCredentials(true);
    }
}

这里 WebConfig 是 configuration class,addCorsMappings 方法内部是在 configure 全局跨域规则。Spring Framework 文档中,CORS 可以通过 Spring MVC configuration 开启,示例也是 @Configuration 类实现 WebMvcConfigurer;addCorsMappings 用来配置全局跨域处理规则。(Home)

3. 应用场景一:第三方支付/短信/OSS 参数配置

这是最常见的 Spring Boot 配置场景:把可变参数放到 config 文件,把它们绑定成 Java 对象,再用 configuration class 生成业务 Bean。

第一步:写 config

# application.yml
sms:
  provider:
    endpoint: "https://sms.example.com"
    access-key: "${SMS_ACCESS_KEY}"
    secret-key: "${SMS_SECRET_KEY}"
    retry-times: 3

第二步:绑定为 configuration properties

@ConfigurationProperties 是 Spring Boot 用来绑定外部配置的注解,可以加在类上,也可以加在 @Configuration 类里的 @Bean 方法上,用于绑定、校验来自 .properties 等外部来源的配置。(Home) 如果用 @ConfigurationPropertiesScan,Spring Boot 会从指定包或当前类所在包开始扫描 @ConfigurationProperties 类型。(Home)

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "sms.provider")
public record SmsProviderProperties(
        String endpoint,
        String accessKey,
        String secretKey,
        int retryTimes
) {
}

启动类:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;

@SpringBootApplication
@ConfigurationPropertiesScan
public class MallApplication {

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

第三步:写 configuration class

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SmsConfig {

    @Bean
    public SmsClient smsClient(SmsProviderProperties properties) {
        SmsClient client = new SmsClient();

        // configure SmsClient
        client.setEndpoint(properties.endpoint());
        client.setAccessKey(properties.accessKey());
        client.setSecretKey(properties.secretKey());
        client.setRetryTimes(properties.retryTimes());

        return client;
    }
}

这段代码里三个词的关系非常典型:

application.yml 中的 sms.provider.*     -> config
SmsProviderProperties                   -> configuration properties
SmsConfig                               -> configuration class
client.setXxx(...)                      -> configure SmsClient
Spring 容器里的 SmsClient Bean          -> 配置完成后的结果

实际业务里,下面这些都适合这样做:

短信平台参数
支付网关参数
对象存储 OSS / S3 参数
微信小程序 AppId / Secret
企业微信、钉钉机器人 Webhook
地图服务 API Key
内部 RPC 服务地址

4. 应用场景二:数据库、Redis、端口等框架配置

很多配置根本不需要自己写 @Configuration 类,因为 Spring Boot 已经提供了自动配置。你只需要写 config:

server:
  port: 8081

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mall
    username: root
    password: 123456
  data:
    redis:
      host: localhost
      port: 6379

Spring Boot 的自动配置会根据你添加的依赖和已有 Bean 尝试自动配置应用;例如官方文档说明,如果类路径上有相关数据库并且你没有手动配置数据库连接 Bean,Spring Boot 可以自动配置内存数据库。(Home)

这里的关系是:

server.port、spring.datasource.*、spring.data.redis.*  -> config
Spring Boot AutoConfiguration                         -> configuration
自动配置内部根据属性创建 DataSource、RedisConnectionFactory 等 -> configure

所以在 Spring Boot 里,不是所有配置都要自己写 XxxConfig。优先顺序通常是:

能用 application.yml 配的,就先用 application.yml
需要创建自定义 Bean 的,再写 @Configuration + @Bean
需要按条件启用的,再加 @ConditionalOnProperty / @Profile

5. 应用场景三:不同环境的配置 dev/test/prod

开发环境和生产环境通常不应该共用同一套配置。

# application.yml
spring:
  profiles:
    active: dev
# application-dev.yml
payment:
  gateway:
    base-url: "https://sandbox-pay.example.com"
# application-prod.yml
payment:
  gateway:
    base-url: "https://pay.example.com"

Spring Boot 也支持在 YAML 文档中使用 spring.config.activate.on-profile,当 profile 表达式匹配时,相应文档会被包含进最终配置合并结果。(Home)

例如:

payment:
  gateway:
    base-url: "https://sandbox-pay.example.com"

---
spring:
  config:
    activate:
      on-profile: prod

payment:
  gateway:
    base-url: "https://pay.example.com"

这里:

application-dev.yml / application-prod.yml  -> 不同环境的 config
profile                                     -> 选择哪一组 configuration
PaymentConfig                               -> 不变
PaymentClient                               -> 启动时根据环境被 configure 成不同地址

这就是“同一份代码,不同环境配置不同”的典型用法。

6. 应用场景四:用配置开关控制某个功能是否启用

比如你有一个“操作日志审计”功能,想通过配置决定是否启用。

config

audit:
  enabled: true

configuration

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AuditConfig {

    @Bean
    @ConditionalOnProperty(
            prefix = "audit",
            name = "enabled",
            havingValue = "true"
    )
    public AuditService auditService() {
        return new AuditService();
    }
}

@ConditionalOnProperty 会根据 Spring Environment 中的属性决定配置是否生效;官方文档说明它可以用 prefix 和 name 指定要检查的属性,也可以通过 havingValue、matchIfMissing 做更精细的匹配。(Home)

这里:

audit.enabled=true           -> config
AuditConfig                  -> configuration class
@ConditionalOnProperty       -> 根据 config 决定 configuration 是否生效
new AuditService()           -> 创建并 configure 审计服务

应用场景包括:

是否开启审计日志
是否开启验证码
是否开启缓存
是否启用 mock 支付
是否启用异步通知
是否接入某个第三方平台

7. 应用场景五:Spring Security 安全配置

现代 Spring Security 常用 SecurityFilterChain Bean 来配置权限规则:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http
                // configure authorization rules
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/login", "/public/**").permitAll()
                        .requestMatchers("/admin/**").hasRole("ADMIN")
                        .anyRequest().authenticated()
                )
                // configure login
                .formLogin(Customizer.withDefaults())
                .build();
    }
}

Spring Security 官方文档说明,Java configuration 会创建名为 springSecurityFilterChain 的 Servlet Filter,它负责保护 URL、验证用户名密码、重定向到登录页等安全工作;HttpSecurity 则用于配置基于 HTTP 请求的 Web 安全。(Home)

这里:

SecurityConfig                       -> configuration class
securityFilterChain(...)             -> 定义安全过滤链 Bean
http.authorizeHttpRequests(...)      -> configure 访问规则
最终 SecurityFilterChain             -> 配置完成后的安全机制

8. @SpringBootApplication 也是一种 Configuration

你的启动类通常长这样:

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

@SpringBootApplication 不是单纯的启动标记。官方文档说明它等价于组合使用 @SpringBootConfiguration、@EnableAutoConfiguration 和 @ComponentScan,表示这是一个配置类,同时启用自动配置和组件扫描。(Home)

所以启动类本身也可以理解成:

主 configuration class
+ 开启 auto-configuration
+ 开启 component scan

不过实际项目中,不建议把所有 @Bean 都堆在启动类里。更清晰的做法是按功能拆分:

config/
  WebConfig.java
  SecurityConfig.java
  RedisConfig.java
  JacksonConfig.java
  SmsConfig.java
properties/
  SmsProviderProperties.java
  PaymentGatewayProperties.java

9. 一个完整记忆模型

可以这样理解 Spring Boot 里的配置流程:

1. 写 config
   application.yml、环境变量、命令行参数

2. 绑定 configuration properties
   @ConfigurationProperties(prefix = "...")

3. 编写 configuration class
   @Configuration + @Bean

4. 在 @Bean 方法或框架回调中 configure 对象
   setXxx(...)、builder.xxx(...)、registry.xxx(...)

5. Spring 容器持有最终配置好的 Bean
   业务代码直接注入使用

例如:

@Service
public class OrderService {

    private final SmsClient smsClient;

    public OrderService(SmsClient smsClient) {
        this.smsClient = smsClient;
    }

    public void createOrder() {
        // 这里不用关心 SmsClient 是怎么 configure 的
        smsClient.send("订单创建成功");
    }
}

业务层只使用 Bean,不应该到处读取配置项。

10. 实战建议

少量简单配置可以用 @Value:

@Value("${app.name}")
private String appName;

多个相关配置优先用 @ConfigurationProperties:

@ConfigurationProperties(prefix = "payment.gateway")
public record PaymentGatewayProperties(
        String baseUrl,
        String apiKey,
        Duration timeout
) {
}

Spring Boot 官方也说明,当配置项很多或具有层级结构时,@Value 会比较繁琐,类型安全的 configuration properties 是更合适的替代方式。(Home)

需要创建 Bean时用 @Configuration + @Bean:

@Configuration
public class PaymentConfig {

    @Bean
    public PaymentClient paymentClient(PaymentGatewayProperties props) {
        return new PaymentClient(props.baseUrl(), props.apiKey(), props.timeout());
    }
}

需要扩展框架行为时用 XxxConfigurer 或框架提供的 builder:

@Configuration
public class WebConfig implements WebMvcConfigurer {
    // configure Spring MVC
}

需要按开关启用功能时用 @ConditionalOnProperty:

@ConditionalOnProperty(prefix = "mock.payment", name = "enabled", havingValue = "true")

最后再压缩成一句:

config 是配置数据;
configuration 是配置类、配置体系或配置结果;
configure 是把配置应用到对象上的动作。

在 Spring Boot 中最常见的组合就是:

application.yml 里写 config
@ConfigurationProperties 读取 config
@Configuration 类组织 configuration
@Bean 方法里 configure 对象
业务代码注入配置好的 Bean