配置管理
LCGYL Framework 提供灵活强大的配置管理功能,支持多种配置源和格式。
版本说明
本文档基于 LCGYL Framework 2.1 版本,包含 YAML 配置、Profile 支持、@ConfigurationProperties 类型安全绑定等新特性。
配置文件
application.properties
默认的配置文件格式。
properties
# 应用配置
app.name=MyApp
app.version=1.0.0
app.description=我的应用
# 服务器配置
server.port=8080
server.host=localhost
# 数据库配置
datasource.url=jdbc:mysql://localhost:3306/mydb
datasource.username=root
datasource.password=secret
datasource.pool.size=10
# 日志配置
logging.level.root=INFO
logging.level.com.example=DEBUGapplication.yaml 2.1+
原生支持 YAML 格式配置文件,无需额外依赖。
yaml
app:
name: MyApp
version: 1.0.0
description: 我的应用
server:
port: 8080
host: localhost
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: secret
pool:
size: 10
logging:
level:
root: INFO
com.example: DEBUG读取配置
使用 @Value 注解
最简单的方式,直接注入配置值。
java
@Component
public class AppConfig {
@Value("app.name")
private String appName;
@Value("app.version")
private String version;
@Value("server.port")
private int port;
// Getters
public String getAppName() {
return appName;
}
}默认值
使用 : 指定默认值。
java
@Component
public class ServerConfig {
@Value("server.port:8080")
private int port; // 如果未配置,默认 8080
@Value("server.host:localhost")
private String host; // 如果未配置,默认 localhost
}类型转换
框架自动进行类型转换。
java
@Component
public class Config {
@Value("server.port")
private int port; // String → int
@Value("feature.enabled")
private boolean enabled; // String → boolean
@Value("timeout.seconds")
private long timeout; // String → long
@Value("rate.limit")
private double rateLimit; // String → double
}集合类型
支持列表和数组。
properties
# application.properties
# 逗号分隔
allowed.hosts=localhost,127.0.0.1,example.com
admin.emails=admin@example.com,support@example.comyaml
# application.yaml
allowed:
hosts:
- localhost
- 127.0.0.1
- example.com
admin:
emails:
- admin@example.com
- support@example.comyaml
# application.yaml
allowed:
hosts:
- localhost
- 127.0.0.1
- example.com
admin:
emails:
- admin@example.com
- support@example.comjava
@Component
public class SecurityConfig {
@Value("allowed.hosts")
private List<String> allowedHosts;
@Value("admin.emails")
private String[] adminEmails;
}配置类 2.1+
@ConfigurationProperties
将配置绑定到 POJO 类,提供类型安全的配置访问。
properties
# application.properties
database.url=jdbc:mysql://localhost:3306/mydb
database.username=root
database.password=secret
database.pool.minSize=5
database.pool.maxSize=20
database.pool.timeout=30000yaml
# application.yaml
database:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: secret
pool:
minSize: 5
maxSize: 20
timeout: 30000java
@Component
@ConfigurationProperties(prefix = "database")
public class DatabaseConfig {
private String url;
private String username;
private String password;
private PoolConfig pool;
// Getters and Setters
public static class PoolConfig {
private int minSize;
private int maxSize;
private long timeout;
// Getters and Setters
}
}使用配置类
java
@Component
public class DatabaseService {
@Inject
private DatabaseConfig config;
public void connect() {
String url = config.getUrl();
String username = config.getUsername();
int poolSize = config.getPool().getMaxSize();
// 使用配置创建连接
}
}环境配置 2.1+
多环境配置文件
resources/
├── application.properties # 通用配置
├── application-dev.properties # 开发环境
├── application-test.properties # 测试环境
└── application-prod.properties # 生产环境激活环境
properties
# application.properties
# 激活开发环境
app.profiles.active=dev或通过命令行:
bash
java -jar myapp.jar --app.profiles.active=prod环境特定配置
properties
# application-dev.properties
server.port=8080
datasource.url=jdbc:mysql://localhost:3306/mydb_dev
logging.level.root=DEBUG
# application-prod.properties
server.port=80
datasource.url=jdbc:mysql://prod-db:3306/mydb
logging.level.root=WARNyaml
# application-dev.yaml
server:
port: 8080
datasource:
url: jdbc:mysql://localhost:3306/mydb_dev
logging:
level:
root: DEBUG
# application-prod.yaml
server:
port: 80
datasource:
url: jdbc:mysql://prod-db:3306/mydb
logging:
level:
root: WARNyaml
# application-dev.yaml
server:
port: 8080
datasource:
url: jdbc:mysql://localhost:3306/mydb_dev
logging:
level:
root: DEBUG
# application-prod.yaml
server:
port: 80
datasource:
url: jdbc:mysql://prod-db:3306/mydb
logging:
level:
root: WARNjava
@Component
public class SecurityConfig {
@Value("server.port")
private int port;
@Value("datasource.url")
private String datasourceUrl;
@Value("logging.level.root")
private String loggingLevel;
}配置优先级
配置源按以下优先级加载(从高到低):
- 命令行参数
- 系统属性
- 环境变量
- application-{profile}.properties
- application.properties
- 默认值
bash
# 命令行参数优先级最高
java -jar myapp.jar --server.port=9090动态配置
配置刷新
java
@Component
public class ConfigRefreshService {
@Inject
private ConfigurationManager configManager;
public void refresh() {
// 重新加载配置
configManager.refresh();
}
}配置监听
监听配置变化。
java
@Component
public class ConfigChangeListener {
@OnConfigChange("server.port")
public void onPortChange(String oldValue, String newValue) {
System.out.println("端口从 " + oldValue + " 变更为 " + newValue);
}
}加密配置
加密敏感信息
properties
# 使用 ENC() 包裹加密值
datasource.password=ENC(encrypted_password_here)
api.key=ENC(encrypted_api_key_here)yaml
# application.yaml
datasource:
password: ENC(encrypted_password_here)
api:
key: ENC(encrypted_api_key_here)配置加密器
java
@Component
public class ConfigEncryptor {
private static final String ALGORITHM = "AES";
private static final String SECRET_KEY = "your-secret-key";
public String encrypt(String value) {
// 加密实现
}
public String decrypt(String encryptedValue) {
// 解密实现
}
}配置验证
使用验证注解
java
@Component
@ConfigurationProperties(prefix = "server")
public class ServerConfig {
@NotNull
@Min(1024)
@Max(65535)
private Integer port;
@NotBlank
private String host;
@Email
private String adminEmail;
// Getters and Setters
}自定义验证
java
@Component
@ConfigurationProperties(prefix = "database")
public class DatabaseConfig {
private String url;
private String username;
private String password;
@PostConstruct
public void validate() {
if (url == null || url.isEmpty()) {
throw new ConfigurationException("数据库 URL 不能为空");
}
if (!url.startsWith("jdbc:")) {
throw new ConfigurationException("无效的数据库 URL");
}
}
}外部配置
从外部文件加载
java
Application app = Application.builder()
.configLocation("file:/etc/myapp/config.properties")
.run(args);从多个位置加载
java
Application app = Application.builder()
.configLocations(
"classpath:application.properties",
"file:/etc/myapp/config.properties",
"file:${user.home}/.myapp/config.properties"
)
.run(args);配置占位符
引用其他配置
properties
app.name=MyApp
app.version=1.0.0
app.fullName=${app.name} v${app.version}
# 结果:MyApp v1.0.0系统属性
properties
# 引用系统属性
user.home=${user.home}
java.version=${java.version}
# 引用环境变量
database.host=${DB_HOST:localhost}条件配置
基于配置的条件
java
@Component
@ConditionalOnProperty(name = "cache.enabled", havingValue = "true")
public class CacheService {
// 只在 cache.enabled=true 时创建
}基于环境的条件
java
@Component
@Profile("dev")
public class DevDatabaseConfig {
// 只在 dev 环境创建
}
@Component
@Profile("prod")
public class ProdDatabaseConfig {
// 只在 prod 环境创建
}最佳实践
1. 使用配置类而不是 @Value
java
// ✅ 推荐:使用配置类
@Component
@ConfigurationProperties(prefix = "database")
public class DatabaseConfig {
private String url;
private String username;
// ...
}
// ❌ 不推荐:到处使用 @Value
@Component
public class ServiceA {
@Value("database.url")
private String url;
}
@Component
public class ServiceB {
@Value("database.url")
private String url;
}2. 提供默认值
java
@Value("server.port:8080")
private int port;
@Value("cache.ttl:3600")
private long cacheTtl;3. 验证配置
java
@PostConstruct
public void validate() {
if (port < 1024 || port > 65535) {
throw new ConfigurationException("无效的端口号: " + port);
}
}4. 不要硬编码配置
java
// ❌ 不推荐
public class Service {
private static final String API_URL = "https://api.example.com";
}
// ✅ 推荐
@Component
public class Service {
@Value("api.url")
private String apiUrl;
}5. 敏感信息加密
properties
# ❌ 不推荐:明文密码
database.password=secret123
# ✅ 推荐:加密密码
database.password=ENC(encrypted_value)6. 使用类型安全的配置
java
// ✅ 推荐:强类型
@ConfigurationProperties(prefix = "server")
public class ServerConfig {
private int port; // 编译时类型检查
}
// ❌ 不推荐:字符串类型
@Value("server.port")
private String port; // 需要手动转换常见问题
Q: 配置文件放在哪里?
A:
- 开发时:
src/main/resources/application.properties - 打包后:JAR 包内的
application.properties - 外部配置:
/etc/myapp/config.properties或${user.home}/.myapp/config.properties
Q: 如何覆盖配置?
A: 使用命令行参数或环境变量。
bash
# 命令行
java -jar myapp.jar --server.port=9090
# 环境变量
export SERVER_PORT=9090
java -jar myapp.jarQ: 配置值为空怎么办?
A: 提供默认值或进行验证。
java
@Value("optional.config:")
private String config; // 空字符串
@Value("optional.config:default")
private String config; // 默认值