Java中读取YAML文件配置信息
1 使用Spring Boot的@ConfigurationProperties
@ConfigurationProperties
是 Spring Boot 提供的一个强大注解,用于将外部配置文件(如 YAML 或 properties 文件)中的属性值绑定到 Java 对象上。它是 Spring Boot 外部化配置的核心功能之一。
示例配置(application.yml)
app:name: MyApplicationversion: 1.0.0servers:- dev.example.com- prod.example.com
创建配置类
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;import java.util.List;@Data
@Component
@ConfigurationProperties(prefix = "app")
public class AppConfig {private String name;private String version;private List<String> servers;}
使用配置类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class MyController {@Autowiredprivate AppConfig appConfig;@GetMapping("/info")public String getAppInfo() {return "App: " + appConfig.getName() + ", Version: " + appConfig.getVersion() +", Servers: " + appConfig.getServers();}
}
2. 使用@Value注解读取单个配置
@Value
是 Spring 框架提供的一个核心注解,用于从属性源(如 properties/YAML 文件、环境变量、系统属性等)中注入值到 Spring 管理的 bean 中。
基本用法
- 注入简单值
@Component
public class MyComponent {@Value("${app.name}")private String appName;@Value("${app.version:1.0.0}") // 带默认值private String appVersion;
}
对应的 application.yml:
app:name: MyApplication# version 未设置时将使用默认值 1.0.0
- 注入系统属性
@Value("${user.home}")
private String userHome; // 注入系统属性 user.home
- 注入环境变量
@Value("${JAVA_HOME}")
private String javaHome; // 注入环境变量 JAVA_HOME
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;@Component
public class MyComponent {@Value("${app.name}")private String appName;@Value("${app.version}")private String appVersion;@Value("${app.description:默认描述}") // 带默认值private String appDescription;// getters and setters
}
3 @ConfigurationProperties 详细介绍
@ConfigurationProperties
是 Spring Boot 提供的一个强大注解,用于将外部配置文件(如 YAML 或 properties 文件)中的属性值绑定到 Java 对象上。它是 Spring Boot 外部化配置的核心功能之一。
基本用法
1. 启用配置属性
首先需要在主类或配置类上添加 @EnableConfigurationProperties
注解:
@SpringBootApplication
@EnableConfigurationProperties
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}
2. 创建配置属性类
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Component
@ConfigurationProperties(prefix = "myapp")
public class MyAppProperties {private String name;private String version;private List<String> servers = new ArrayList<>();private Database database;// getters and setterspublic static class Database {private String url;private String username;private String password;// getters and setters}
}
3. 对应的 YAML 配置
myapp:name: My Applicationversion: 1.0.0servers:- server1.example.com- server2.example.comdatabase:url: jdbc:mysql://localhost:3306/mydbusername: adminpassword: secret
核心特性
1. 前缀绑定
prefix
属性指定了配置属性的前缀:
@ConfigurationProperties(prefix = "myapp")
2. 宽松绑定 (Relaxed Binding)
Spring Boot 支持多种属性命名风格自动匹配:
myapp.database.url
(properties 风格)myapp.database-url
(kebab-case 风格)myapp.databaseUrl
(camelCase 风格)MYAPP_DATABASE_URL
(环境变量风格)
3. 类型安全
配置属性会自动转换为目标类型:
myapp:timeout: 5000 # 自动转换为 intenabled: true # 自动转换为 booleanratio: 0.8 # 自动转换为 float
4. 嵌套属性
支持多层嵌套的配置结构:
public class MyAppProperties {private Database database;public static class Database {private String url;private int maxConnections;}
}
5. 集合类型支持
支持 List、Set、Map 等集合类型:
myapp:servers:- server1- server2endpoints:api: /api/v1auth: /auth
对应的 Java 类:
private List<String> servers;
private Map<String, String> endpoints;
高级特性
1. 属性验证
可以结合 JSR-303 验证注解:
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Min;@ConfigurationProperties(prefix = "myapp")
@Validated
public class MyAppProperties {@NotEmptyprivate String name;@Min(1)private int version;// ...
}
2. 默认值
可以在字段声明时提供默认值:
private int timeout = 3000; // 默认值 3000
3. 构造函数绑定 (Spring Boot 2.2+)
支持不可变对象的构造函数绑定:
@ConfigurationProperties(prefix = "myapp")
public class MyAppProperties {private final String name;private final int version;public MyAppProperties(String name, int version) {this.name = name;this.version = version;}// 只需要 getters
}
4. 第三方组件配置
可以为第三方库创建配置属性类:
@ConfigurationProperties(prefix = "thirdparty.service")
public class ThirdPartyServiceProperties {private String endpoint;private String apiKey;// getters and setters
}
最佳实践
- 集中管理配置:将相关配置属性组织在一个类中
- 使用嵌套类:对于复杂配置,使用静态内部类
- 添加验证:确保配置值的有效性
- 提供文档:使用
@ConfigurationProperties
的description
属性或元数据文件 - 考虑不可变性:对于生产环境配置,考虑使用构造函数绑定
配置元数据
为了在 IDE 中获得更好的支持,可以创建 additional-spring-configuration-metadata.json
文件:
{"properties": [{"name": "myapp.name","type": "java.lang.String","description": "The name of the application."},{"name": "myapp.database.url","type": "java.lang.String","description": "JDBC URL for the database connection."}]
}
与 @Value
对比
特性 | @ConfigurationProperties | @Value |
---|---|---|
松散绑定 | 支持 | 不支持 |
元数据支持 | 支持 | 不支持 |
SpEL 表达式 | 不支持 | 支持 |
复杂类型 | 支持 | 有限支持 |
验证 | 支持 | 不支持 |
多个属性关联 | 方便 | 不方便 |
常见问题解决
-
属性未绑定:
- 确保类有
@Component
或通过@EnableConfigurationProperties
注册 - 检查前缀是否正确
- 确保属性有 setter 方法(除非使用构造函数绑定)
- 确保类有
-
类型不匹配:
- 检查 YAML 中的值是否能转换为目标类型
- 考虑使用
@DurationUnit
或@DataSizeUnit
指定单位
-
IDE 警告:
- 添加
spring-boot-configuration-processor
依赖 - 生成配置元数据
- 添加
@ConfigurationProperties
是 Spring Boot 中处理外部配置的强大工具,特别适合管理大量相关配置属性,提供了类型安全、验证和良好组织结构的优势。