在 Spring Boot 中,读取配置文件(如 application.properties/application.yml)的方式丰富且灵活,核心可分为基础注解式 、编程式 、类型安全绑定三大类,以下是主流方式的详细总结:
一、核心前提:配置文件基础
Spring Boot 默认加载 src/main/resources 下的 application.properties 或 application.yml,也可通过 spring.config.name/spring.config.location 自定义配置文件路径。
方式1:@Value 注解(基础单个属性读取)
核心特点
最基础、轻量的方式,直接绑定单个配置项到字段/方法参数,支持简单类型转换、默认值、SpEL 表达式。
使用示例
1. 配置文件(application.yml)
yaml
app:
name: demo-app
port: 8080
desc: ${app.name}-${app.port} # SpEL 拼接
2. 代码绑定
java
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class AppConfig {
// 直接绑定单个属性
@Value("${app.name}")
private String appName;
// 绑定并设置默认值(配置不存在时使用)
@Value("${app.version:1.0.0}")
private String appVersion;
// 绑定 SpEL 拼接的属性
@Value("${app.desc}")
private String appDesc;
}
优缺点
- ✅ 优点:简单易用,适合少量零散配置;
- ❌ 缺点:不支持复杂对象、无类型校验、配置多时代码冗余,无法自动刷新(需结合
@RefreshScope)。
方式2:@ConfigurationProperties(类型安全绑定,推荐)
核心特点
将一组相关配置绑定到 Java 实体类,支持嵌套对象、类型校验、前缀分组,是 Spring Boot 推荐的配置绑定方式。
使用步骤
1. 配置文件(application.yml)
yaml
app:
name: demo-app
port: 8080
database:
url: jdbc:mysql://localhost:3306/test
username: root
password: 123456
servers:
- 192.168.1.1
- 192.168.1.2
2. 绑定实体类
java
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
// 前缀指定配置分组,需配合 @Component 或 @EnableConfigurationProperties 生效
@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {
private String name;
private Integer port;
private Database database; // 嵌套对象
private List<String> servers; // 集合
// 嵌套类
public static class Database {
private String url;
private String username;
private String password;
// getter/setter
}
// 必须提供 getter/setter(Spring 反射赋值)
public String getName() { return name; }
public void setName(String name) { this.name = name; }
// 其他字段的 getter/setter
}
3. 启用配置(可选)
若实体类未加 @Component,需在配置类中通过 @EnableConfigurationProperties 启用:
java
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(AppProperties.class)
public class Config {
}
增强特性
-
支持 JSR-380 校验(加
@Validated+ 校验注解):java@Component @ConfigurationProperties(prefix = "app") @Validated public class AppProperties { @NotBlank(message = "应用名称不能为空") private String name; // ... } -
支持配置自动刷新(结合
@RefreshScope)。
优缺点
- ✅ 优点:类型安全、支持嵌套/集合、配置分组清晰、可校验;
- ❌ 缺点:需编写实体类,略繁琐(但可通过 Lombok 简化)。
方式3:Environment 接口(编程式读取)
核心特点
Spring 核心环境接口,可动态读取所有配置(包括系统属性、环境变量、配置文件),支持配置占位符解析。
使用示例
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
@Component
public class EnvConfig {
@Autowired
private Environment env;
public void getConfig() {
// 读取单个配置
String appName = env.getProperty("app.name");
// 读取并指定默认值
Integer appPort = env.getProperty("app.port", Integer.class, 8080);
// 读取嵌套配置
String dbUrl = env.getProperty("app.database.url");
}
}
扩展能力
- 支持配置文件激活:
env.getActiveProfiles()(获取激活的环境,如 dev/prod); - 支持判断配置是否存在:
env.containsProperty("app.name")。
优缺点
- ✅ 优点:灵活,支持动态读取、多环境适配,无需绑定实体类;
- ❌ 缺点:无类型安全(需手动转换类型)、零散读取时代码冗余。
方式4:原生 Properties/yml 读取(手动加载)
核心特点
脱离 Spring 容器,手动加载配置文件(适合非 Spring 管理的代码),支持 properties 和 yml 格式。
示例1:手动读取 properties 文件
java
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class ManualPropertiesReader {
public static void main(String[] args) throws IOException {
Properties props = new Properties();
// 加载 classpath 下的配置文件
try (InputStream is = ManualPropertiesReader.class.getClassLoader().getResourceAsStream("application.properties")) {
props.load(is);
String appName = props.getProperty("app.name");
}
}
}
示例2:手动读取 yml 文件(需依赖 snakeyaml)
xml
<!-- pom.xml 引入依赖 -->
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</dependency>
java
import org.yaml.snakeyaml.Yaml;
import java.io.InputStream;
import java.util.Map;
public class ManualYmlReader {
public static void main(String[] args) {
Yaml yaml = new Yaml();
try (InputStream is = ManualYmlReader.class.getClassLoader().getResourceAsStream("application.yml")) {
Map<String, Object> data = yaml.load(is);
// 读取嵌套配置
Map<String, Object> app = (Map<String, Object>) data.get("app");
String appName = (String) app.get("name");
}
}
}
优缺点
- ✅ 优点:完全脱离 Spring,灵活控制加载逻辑;
- ❌ 缺点:需手动处理文件加载、类型转换、嵌套结构,无 Spring 自动装配能力。
方式5:@PropertySource 加载自定义配置文件
核心特点
加载非默认名称/路径的配置文件(如 custom.properties),配合 @Value 或 @ConfigurationProperties 使用。
使用示例
1. 自定义配置文件(custom.properties)
properties
custom.name=my-custom-app
custom.age=20
2. 加载并绑定
java
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Value;
@Component
// 加载自定义 properties 文件(仅支持 properties,不直接支持 yml)
@PropertySource("classpath:custom.properties")
public class CustomConfig {
@Value("${custom.name}")
private String customName;
}
扩展:加载 yml 文件(需自定义工厂)
@PropertySource 原生不支持 yml,需自定义 PropertySourceFactory:
java
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import org.yaml.snakeyaml.Yaml;
import java.util.Map;
public class YmlPropertySourceFactory implements PropertySourceFactory {
@Override
public org.springframework.core.env.PropertySource<?> createPropertySource(String name, EncodedResource resource) {
Yaml yaml = new Yaml();
Map<String, Object> data = yaml.load(resource.getInputStream());
return new MapPropertySource(resource.getResource().getFilename(), data);
}
}
使用:
java
@PropertySource(value = "classpath:custom.yml", factory = YmlPropertySourceFactory.class)
@Component
public class CustomYmlConfig {
@Value("${custom.name}")
private String customName;
}
优缺点
- ✅ 优点:支持加载自定义配置文件,补充默认配置;
- ❌ 缺点:原生不支持 yml,需自定义工厂;多文件加载时需逐个声明。
各方式对比与选型建议
| 方式 | 类型安全 | 支持嵌套/集合 | 配置分组 | 手动加载 | 推荐场景 |
|---|---|---|---|---|---|
| @Value | ❌ | ❌ | ❌ | ❌ | 少量零散配置、简单值绑定 |
| @ConfigurationProperties | ✅ | ✅ | ✅ | ❌ | 大量相关配置、类型安全场景 |
| Environment | ❌ | ✅(手动解析) | ❌ | ❌ | 动态读取、多环境适配、编程式 |
| 原生手动加载 | ❌ | ✅(手动解析) | ❌ | ✅ | 非 Spring 管理代码、自定义加载 |
| @PropertySource | 取决于绑定方式 | ✅ | ✅ | ❌ | 加载自定义配置文件 |
选型总结
- 日常开发优先用
@ConfigurationProperties(类型安全、易维护); - 零散简单配置用
@Value; - 动态读取/多环境适配用
Environment; - 非 Spring 代码或自定义加载逻辑用原生手动读取;
- 需加载自定义配置文件时结合
@PropertySource。