Appearance
SpringBoot配置文件读取的各种方式
| 方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
@Value | 单个、少量配置注入 | 简单直观 | 松散绑定差,不支持复杂对象 |
@ConfigurationProperties | 结构化、批量配置 | 类型安全、支持校验、IDE提示 | 需额外注解/类定义 |
Environment | 运行时动态获取 | 灵活、可编程 | 无编译期检查,代码冗余 |
@PropertySource | 加载自定义非标准文件 | 扩展性强 | 仅支持 Properties (YAML需特殊处理) |
⚠️ Spring Boot 3 重要变更
- 必须使用 JDK 17+
@ConfigurationProperties完美支持 Java Record 类(不可变配置)- 推荐使用
@ConfigurationPropertiesScan或@EnableConfigurationProperties替代旧的@Component扫描方式
准备工作
添加依赖(可选但推荐)
为了获得 IDE 自动补全和元数据提示,建议添加:
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>示例配置文件 application.yml
yaml
app:
name: MyAwesomeApp
version: 3.0.0
features:
enable-cache: true
max-retry: 3
mail:
host: smtp.example.com
port: 587
credentials:
username: admin
password: secret四种读取方式详解
方式一:@Value —— 简单注入
适合注入单个值,支持 SpEL 表达式和默认值。
java
@RestController
public class SimpleController {
// 基本注入
@Value("${app.name}")
private String appName;
// 带默认值(冒号后为默认值)
@Value("${app.description:No description provided}")
private String description;
// SpEL 表达式
@Value("#{${app.features.max-retry} * 2}")
private int doubleRetry;
}💡 注意:
@Value不支持直接映射 Map/List 等复杂结构,也不支持从 YAML 的层级结构中自动绑定嵌套对象。
方式二:@ConfigurationProperties —— ⭐ 最佳实践
✅ 推荐:使用 Record(Spring Boot 3 新特性)
java
// 不可变、线程安全、简洁
@ConfigurationProperties(prefix = "app")
public record AppProperties(
String name,
String version,
Features features,
Mail mail
) {
// 嵌套配置也用 Record
public record Features(boolean enableCache, int maxRetry) {}
public record Mail(String host, int port, Credentials credentials) {}
public record Credentials(String username, String password) {}
}传统 POJO 写法(仍然有效)
java
@ConfigurationProperties(prefix = "app")
@Data // Lombok
public class AppProperties {
private String name;
private String version;
private Features features;
@Data
public static class Features {
private boolean enableCache;
private int maxRetry;
}
}注册配置类的三种方式
java
// 方式A:在启动类或配置类上启用(推荐)
@EnableConfigurationProperties(AppProperties.class)
@SpringBootApplication
public class Application { }
// 方式B:全局扫描(适合多个配置类)
@ConfigurationPropertiesScan("com.example.config")
@SpringBootApplication
public class Application { }
// 方式C:直接在配置类上加 @Component(旧方式,仍可用但不推荐)
@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties { }添加参数校验
java
@ConfigurationProperties(prefix = "app")
@Validated // ← 开启校验
public record AppProperties(
@NotBlank String name,
@Min(1) @Max(10) int maxRetry,
@Email String adminEmail
) {}需引入
spring-boot-starter-validation依赖。
方式三:Environment —— 编程式读取
适合在框架代码、条件逻辑中动态获取配置。
java
@Service
public class DynamicConfigService {
private final Environment env;
public DynamicConfigService(Environment env) {
this.env = env;
}
public String getDbUrl() {
// 返回 Optional 风格的安全获取
return env.getProperty("spring.datasource.url", "jdbc:h2:mem:default");
}
public boolean isProfileActive(String profile) {
return env.acceptsProfiles(Profile.of(profile));
}
}方式四:@PropertySource —— 加载自定义文件
java
@Configuration
@PropertySource("classpath:custom-config.properties")
// ⚠️ YAML 文件不直接被 @PropertySource 支持!
// 如需加载自定义 YAML,需自定义 PropertySourceFactory
public class CustomConfig { }自定义 YAML 工厂示例:
java
public class YamlPropertySourceFactory implements PropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource)
throws IOException {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(resource.getResource());
Properties properties = factory.getObject();
return new PropertiesPropertySource(
resource.getResource().getFilename(), properties
);
}
}
// 使用
@PropertySource(value = "classpath:custom.yml", factory = YamlPropertySourceFactory.class)配置优先级(从高到低)
1. 命令行参数 (--app.name=xxx)
2. JNDI 属性
3. Java 系统属性 (System.getProperties())
4. OS 环境变量
5. application-{profile}.yml / .properties
6. application.yml / .properties
7. @PropertySource 导入的文件
8. 默认属性 (SpringApplication.setDefaultProperties)🔑 记忆口诀:外部 > 内部,命令行 > 文件,Profile > 通用
选型决策树
需要读取配置?
├── 只读 1~2 个简单值 → @Value
├── 结构化 / 一组相关配置 → @ConfigurationProperties
│ ├── 不可变 / JDK17+ → Record ⭐
│ └── 需要可变 / 兼容旧代码 → POJO
├── 运行时动态决定 key → Environment
└── 加载非标准外部文件 → spring.config.import / @PropertySource📌 总结:在 Spring Boot 3 项目中,优先使用
@ConfigurationProperties+ Record 作为配置读取的标准范式。它提供了类型安全、IDE 友好、校验支持和不可变性保障,是现代 Spring 应用配置管理的最佳实践。
