本文目录导读:

- 基础配置实体类
- 核心配置管理器
- 配置源接口和实现
- 配置缓存实现
- 使用示例
- 高级应用:注解驱动的配置绑定
- 配置文件示例 (
application.properties) - Maven依赖 (
pom.xml) - 关键特性说明
我来为您提供一个完整的Java配置管理案例,包含多种常见场景和最佳实践。
基础配置实体类
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Properties;
import java.io.InputStream;
import java.io.IOException;
/**
* 配置项实体类
*/
public class ConfigItem {
private String key;
private String value;
private String description;
private String group;
private boolean isSensitive;
private String dataType; // string, int, boolean, double, json
public ConfigItem() {}
public ConfigItem(String key, String value, String description,
String group, boolean isSensitive, String dataType) {
this.key = key;
this.value = value;
this.description = description;
this.group = group;
this.isSensitive = isSensitive;
this.dataType = dataType;
}
// Getters and Setters
public String getKey() { return key; }
public void setKey(String key) { this.key = key; }
public String getValue() { return value; }
public void setValue(String value) { this.value = value; }
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
public String getGroup() { return group; }
public void setGroup(String group) { this.group = group; }
public boolean isSensitive() { return isSensitive; }
public void setSensitive(boolean sensitive) { isSensitive = sensitive; }
public String getDataType() { return dataType; }
public void setDataType(String dataType) { this.dataType = dataType; }
}
核心配置管理器
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
/**
* 配置管理器 - 支持热更新、监听、缓存
*/
public class ConfigManager {
private static volatile ConfigManager instance;
// 配置存储
private final Map<String, ConfigItem> configs = new ConcurrentHashMap<>();
// 配置变更监听器
private final Map<String, List<Consumer<ConfigItem>>> listeners = new ConcurrentHashMap<>();
// 全局监听器
private final List<Consumer<String>> globalListeners = new ArrayList<>();
// 配置来源
private ConfigSource source;
// 缓存管理
private final ConfigCache cache;
// 刷新锁
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
// 初始化状态
private final AtomicBoolean initialized = new AtomicBoolean(false);
// 定期刷新调度器
private ScheduledExecutorService scheduler;
private ScheduledFuture<?> refreshTask;
private ConfigManager() {
this.cache = new ConfigCache(1000); // 默认缓存1秒
initScheduler();
}
public static ConfigManager getInstance() {
if (instance == null) {
synchronized (ConfigManager.class) {
if (instance == null) {
instance = new ConfigManager();
}
}
}
return instance;
}
/**
* 初始化配置源
*/
public void init(ConfigSource source) {
this.source = source;
loadAllConfigs();
initialized.set(true);
}
/**
* 加载所有配置
*/
private void loadAllConfigs() {
if (source == null) return;
lock.writeLock().lock();
try {
Map<String, ConfigItem> loadedConfigs = source.loadAllConfigs();
if (loadedConfigs != null) {
// 对比旧配置,找出变化
detectChanges(configs, loadedConfigs);
configs.clear();
configs.putAll(loadedConfigs);
}
} finally {
lock.writeLock().unlock();
}
}
/**
* 检测配置变更并通知
*/
private void detectChanges(Map<String, ConfigItem> oldConfigs,
Map<String, ConfigItem> newConfigs) {
if (oldConfigs.isEmpty()) return;
// 检查更新和删除
for (Map.Entry<String, ConfigItem> entry : oldConfigs.entrySet()) {
String key = entry.getKey();
ConfigItem newItem = newConfigs.get(key);
if (newItem == null) {
// 配置被删除
notifyListeners(key, null);
} else if (!Objects.equals(entry.getValue().getValue(), newItem.getValue())) {
// 配置值变更
notifyListeners(key, newItem);
}
}
// 检查新增
for (String key : newConfigs.keySet()) {
if (!oldConfigs.containsKey(key)) {
notifyListeners(key, newConfigs.get(key));
}
}
}
/**
* 获取配置(带缓存)
*/
public String getConfig(String key) {
return getConfig(key, null);
}
/**
* 获取配置(带默认值)
*/
public String getConfig(String key, String defaultValue) {
lock.readLock().lock();
try {
// 尝试从缓存获取
Object cached = cache.get(key);
if (cached != null) {
return (String) cached;
}
// 从配置存储获取
ConfigItem item = configs.get(key);
String value = item != null ? item.getValue() : defaultValue;
// 缓存结果
cache.put(key, value);
return value;
} finally {
lock.readLock().unlock();
}
}
/**
* 获取带类型的配置
*/
public int getInt(String key, int defaultValue) {
String value = getConfig(key);
if (value == null) return defaultValue;
try {
return Integer.parseInt(value);
} catch (NumberFormatException e) {
return defaultValue;
}
}
public boolean getBoolean(String key, boolean defaultValue) {
String value = getConfig(key);
if (value == null) return defaultValue;
return Boolean.parseBoolean(value);
}
public double getDouble(String key, double defaultValue) {
String value = getConfig(key);
if (value == null) return defaultValue;
try {
return Double.parseDouble(value);
} catch (NumberFormatException e) {
return defaultValue;
}
}
/**
* 设置配置(并通知变更)
*/
public void setConfig(String key, String value) {
setConfig(key, value, true);
}
/**
* 设置配置
*/
public void setConfig(String key, String value, boolean notifyChange) {
lock.writeLock().lock();
try {
ConfigItem oldItem = configs.get(key);
if (oldItem == null) {
// 新增配置
ConfigItem newItem = new ConfigItem(key, value, "", "default", false, "string");
configs.put(key, newItem);
if (notifyChange) {
notifyListeners(key, newItem);
}
} else {
// 更新配置
oldItem.setValue(value);
oldItem.setDataType(detectDataType(value));
// 更新到配置源
if (source != null) {
source.updateConfig(key, value);
}
if (notifyChange) {
notifyListeners(key, oldItem);
}
}
// 更新缓存
cache.put(key, value);
} finally {
lock.writeLock().unlock();
}
}
/**
* 批量设置配置
*/
public void setConfigs(Map<String, String> configMap) {
lock.writeLock().lock();
try {
for (Map.Entry<String, String> entry : configMap.entrySet()) {
setConfig(entry.getKey(), entry.getValue(), false);
}
// 触发全局变更通知
notifyGlobalListeners("batch_update");
} finally {
lock.writeLock().unlock();
}
}
/**
* 注册配置监听器
*/
public void registerListener(String key, Consumer<ConfigItem> listener) {
listeners.computeIfAbsent(key, k -> new CopyOnWriteArrayList<>())
.add(listener);
}
/**
* 注册全局监听器
*/
public void registerGlobalListener(Consumer<String> listener) {
globalListeners.add(listener);
}
/**
* 通知指定配置的监听器
*/
private void notifyListeners(String key, ConfigItem item) {
// 通知指定key的监听器
List<Consumer<ConfigItem>> keyListeners = listeners.get(key);
if (keyListeners != null) {
for (Consumer<ConfigItem> listener : keyListeners) {
try {
listener.accept(item);
} catch (Exception e) {
// 异常处理
}
}
}
// 通知全局监听器
notifyGlobalListeners(key);
}
/**
* 通知全局监听器
*/
private void notifyGlobalListeners(String key) {
for (Consumer<String> listener : globalListeners) {
try {
listener.accept(key);
} catch (Exception e) {
// 异常处理
}
}
}
/**
* 刷新配置
*/
public void refresh() {
if (source != null) {
loadAllConfigs();
}
}
/**
* 定时刷新
*/
public void scheduleRefresh(long interval, TimeUnit unit) {
if (refreshTask != null) {
refreshTask.cancel(false);
}
refreshTask = scheduler.scheduleAtFixedRate(() -> {
try {
refresh();
} catch (Exception e) {
// 刷新失败日志
}
}, interval, interval, unit);
}
/**
* 初始化调度器
*/
private void initScheduler() {
scheduler = Executors.newSingleThreadScheduledExecutor(r -> {
Thread t = new Thread(r, "config-refresh-scheduler");
t.setDaemon(true);
return t;
});
}
/**
* 检测数据类型
*/
private String detectDataType(String value) {
if (value == null) return "string";
try {
Integer.parseInt(value);
return "int";
} catch (NumberFormatException e) {
// Not an int
}
try {
Double.parseDouble(value);
return "double";
} catch (NumberFormatException e) {
// Not a double
}
if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) {
return "boolean";
}
// JSON检查
if (value.trim().startsWith("{") || value.trim().startsWith("[")) {
return "json";
}
return "string";
}
/**
* 获取所有配置
*/
public Map<String, ConfigItem> getAllConfigs() {
lock.readLock().lock();
try {
return new HashMap<>(configs);
} finally {
lock.readLock().unlock();
}
}
/**
* 删除配置
*/
public void removeConfig(String key) {
lock.writeLock().lock();
try {
configs.remove(key);
cache.remove(key);
// 通知监听器
notifyListeners(key, null);
// 从配置源删除
if (source != null) {
source.deleteConfig(key);
}
} finally {
lock.writeLock().unlock();
}
}
/**
* 关闭配置管理器
*/
public void shutdown() {
if (refreshTask != null) {
refreshTask.cancel(true);
}
scheduler.shutdown();
if (source != null) {
source.close();
}
}
}
配置源接口和实现
import java.util.Map;
/**
* 配置源接口
*/
public interface ConfigSource {
Map<String, ConfigItem> loadAllConfigs();
void updateConfig(String key, String value);
void deleteConfig(String key);
void close();
}
/**
* 基于Properties文件的配置源
*/
public class PropertiesConfigSource implements ConfigSource {
private final String filePath;
private final Properties properties = new Properties();
public PropertiesConfigSource(String filePath) {
this.filePath = filePath;
loadProperties();
}
private void loadProperties() {
try (InputStream input = getClass().getClassLoader()
.getResourceAsStream(filePath)) {
if (input != null) {
properties.load(input);
}
} catch (IOException e) {
throw new RuntimeException("Failed to load properties file: " + filePath, e);
}
}
@Override
public Map<String, ConfigItem> loadAllConfigs() {
Map<String, ConfigItem> configMap = new HashMap<>();
for (String key : properties.stringPropertyNames()) {
ConfigItem item = new ConfigItem();
item.setKey(key);
item.setValue(properties.getProperty(key));
item.setGroup("properties");
configMap.put(key, item);
}
return configMap;
}
@Override
public void updateConfig(String key, String value) {
properties.setProperty(key, value);
saveToFile();
}
@Override
public void deleteConfig(String key) {
properties.remove(key);
saveToFile();
}
private void saveToFile() {
// 保存到文件
try (OutputStream output = new FileOutputStream(filePath)) {
properties.store(output, "Config Updated at " + new Date());
} catch (IOException e) {
// 处理异常
}
}
@Override
public void close() {
// 清理资源
}
}
/**
* 基于数据库的配置源
*/
public class DatabaseConfigSource implements ConfigSource {
private final DataSource dataSource;
public DatabaseConfigSource(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public Map<String, ConfigItem> loadAllConfigs() {
Map<String, ConfigItem> configMap = new HashMap<>();
String sql = "SELECT `key`, `value`, `description`, `group_name`, " +
"`is_sensitive`, `data_type` FROM configs";
try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
ConfigItem item = new ConfigItem(
rs.getString("key"),
rs.getString("value"),
rs.getString("description"),
rs.getString("group_name"),
rs.getBoolean("is_sensitive"),
rs.getString("data_type")
);
configMap.put(item.getKey(), item);
}
} catch (SQLException e) {
throw new RuntimeException("Failed to load configs from database", e);
}
return configMap;
}
@Override
public void updateConfig(String key, String value) {
String sql = "UPDATE configs SET value = ? WHERE `key` = ?";
try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, value);
ps.setString(2, key);
ps.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException("Failed to update config", e);
}
}
@Override
public void deleteConfig(String key) {
String sql = "DELETE FROM configs WHERE `key` = ?";
try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, key);
ps.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException("Failed to delete config", e);
}
}
@Override
public void close() {
// 清理资源
}
}
配置缓存实现
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
/**
* 配置缓存
*/
public class ConfigCache {
private final long defaultTtl;
private final Map<String, CacheEntry> cacheMap = new ConcurrentHashMap<>();
private static class CacheEntry {
private final Object value;
private final long expireTime;
CacheEntry(Object value, long expireTime) {
this.value = value;
this.expireTime = expireTime;
}
boolean isExpired() {
return System.currentTimeMillis() > expireTime;
}
}
public ConfigCache(long defaultTtlMillis) {
this.defaultTtl = defaultTtlMillis;
}
public void put(String key, Object value) {
put(key, value, defaultTtl);
}
public void put(String key, Object value, long ttlMillis) {
long expireTime = System.currentTimeMillis() + ttlMillis;
cacheMap.put(key, new CacheEntry(value, expireTime));
}
public Object get(String key) {
CacheEntry entry = cacheMap.get(key);
if (entry == null) return null;
if (entry.isExpired()) {
cacheMap.remove(key);
return null;
}
return entry.value;
}
public void remove(String key) {
cacheMap.remove(key);
}
public void clear() {
cacheMap.clear();
}
public int size() {
return cacheMap.size();
}
}
使用示例
/**
* 配置管理示例代码
*/
public class ConfigExample {
public static void main(String[] args) throws InterruptedException {
// 1. 初始化配置管理器
ConfigManager configManager = ConfigManager.getInstance();
// 2. 配置数据源(这里使用properties文件)
PropertiesConfigSource source = new PropertiesConfigSource("application.properties");
configManager.init(source);
// 3. 添加配置监听器
configManager.registerListener("app.name", (configItem) -> {
System.out.println("App name changed to: " + configItem.getValue());
});
configManager.registerGlobalListener((key) -> {
System.out.println("Config changed: " + key);
});
// 4. 读取配置
String appName = configManager.getConfig("app.name", "MyApp");
int port = configManager.getInt("server.port", 8080);
boolean debug = configManager.getBoolean("app.debug", false);
System.out.println("App Name: " + appName);
System.out.println("Port: " + port);
System.out.println("Debug: " + debug);
// 5. 批量设置配置
Map<String, String> newConfigs = new HashMap<>();
newConfigs.put("server.host", "localhost");
newConfigs.put("server.timeout", "5000");
newConfigs.put("database.poolSize", "20");
configManager.setConfigs(newConfigs);
// 6. 定时刷新配置(每10秒刷新一次)
configManager.scheduleRefresh(10, TimeUnit.SECONDS);
// 7. 模拟运行一段时间
Thread.sleep(30000);
// 8. 关闭配置管理器
configManager.shutdown();
}
}
高级应用:注解驱动的配置绑定
import java.lang.annotation.*;
import java.lang.reflect.Field;
/**
* 配置注解
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ConfigValue {
String key();
String defaultValue() default "";
}
/**
* 配置绑定器
*/
public class ConfigBinder {
public static <T> T bind(T target, ConfigManager configManager) {
Class<?> clazz = target.getClass();
for (Field field : clazz.getDeclaredFields()) {
if (field.isAnnotationPresent(ConfigValue.class)) {
ConfigValue annotation = field.getAnnotation(ConfigValue.class);
String value = configManager.getConfig(annotation.key(),
annotation.defaultValue());
field.setAccessible(true);
try {
field.set(target, convertValue(value, field.getType()));
} catch (IllegalAccessException e) {
// 处理异常
}
}
}
return target;
}
private static Object convertValue(String value, Class<?> type) {
if (type == String.class) {
return value;
} else if (type == int.class || type == Integer.class) {
return Integer.parseInt(value);
} else if (type == boolean.class || type == Boolean.class) {
return Boolean.parseBoolean(value);
} else if (type == double.class || type == Double.class) {
return Double.parseDouble(value);
} else if (type == long.class || type == Long.class) {
return Long.parseLong(value);
}
return value;
}
}
/**
* 配置绑定示例
*/
public class AppConfig {
@ConfigValue(key = "app.name", defaultValue = "MyApp")
private String appName;
@ConfigValue(key = "server.port", defaultValue = "8080")
private int port;
@ConfigValue(key = "app.debug", defaultValue = "false")
private boolean debug;
// Getters
public String getAppName() { return appName; }
public int getPort() { return port; }
public boolean isDebug() { return debug; }
public static void main(String[] args) {
ConfigManager configManager = ConfigManager.getInstance();
// 设置一些配置
configManager.setConfig("app.name", "TestApp");
configManager.setConfig("server.port", "9090");
configManager.setConfig("app.debug", "true");
// 绑定配置到对象
AppConfig appConfig = ConfigBinder.bind(new AppConfig(), configManager);
System.out.println("App Name: " + appConfig.getAppName());
System.out.println("Port: " + appConfig.getPort());
System.out.println("Debug: " + appConfig.isDebug());
}
}
配置文件示例 (application.properties)
# 应用配置 app.name=MyApplication app.version=1.0.0 app.debug=false app.environment=development app.timezone=Asia/Shanghai # 服务器配置 server.host=0.0.0.0 server.port=8080 server.maxThreads=200 server.minSpareThreads=50 server.sessionTimeout=30m server.compression.enabled=true # 数据库配置 database.url=jdbc:mysql://localhost:3306/mydb database.username=admin database.password=secret database.poolSize=20 database.maxConnection=100 database.connectionTimeout=3000 database.idleTimeout=60000 # 缓存配置 cache.type=redis cache.host=localhost cache.port=6379 cache.password=redis123 cache.ttl=3600 cache.maxMemory=256MB # 日志配置 logging.level.root=INFO logging.level.com.example=DEBUG logging.file.name=application.log logging.file.maxSize=10MB logging.file.maxHistory=7 # 功能开关 feature.newUI.enabled=true feature.advancedSearch.enabled=false feature.cache.enabled=true feature.rateLimit.enabled=false # 第三方服务配置 sms.provider=aliyun sms.accessKeyId=your-access-key sms.accessKeySecret=your-secret-key sms.signName=YourCompany # 邮件服务配置 mail.smtp.host=smtp.example.com mail.smtp.port=587 mail.smtp.username=user@example.com mail.smtp.password=password mail.from=no-reply@example.com
Maven依赖 (pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>config-management</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- 数据库连接池 -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>5.0.1</version>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!-- SLF4J日志 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>
<!-- JSON处理 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
关键特性说明
- 单例模式:使用双重检查锁实现线程安全的单例
- 读写锁:使用ReentrantReadWriteLock保证并发安全
- 缓存机制:支持配置缓存,提高读取性能
- 监听器模式:支持配置变更监听和通知
- 热更新:支持定时刷新配置,无需重启应用
- 多数据源支持:支持Properties文件、数据库等不同配置源
- 类型转换:自动检测和转换配置值的类型
- 注解驱动:通过注解自动绑定配置到对象
这个配置管理案例提供了完整的实现,您可以按需扩展和调整。