Java动态配置案例如何开发

wen java案例 27

本文目录导读:

Java动态配置案例如何开发

  1. 基于配置文件的热加载方案
  2. 基于数据库的动态配置方案
  3. 使用开源配置中心
  4. 实战案例:动态线程池配置

我来详细介绍Java动态配置的几种开发方案,从简单到复杂的实战案例。

基于配置文件的热加载方案

使用Spring Cloud Config + Git

// 1. 服务端配置 (config-server)
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }
}
// application.yml
server:
  port: 8888
spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/your-repo/config-repo
          search-paths: '{application}'
// 2. 客户端配置 (config-client)
@SpringBootApplication
@RefreshScope  // 支持动态刷新
public class ConfigClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigClientApplication.class, args);
    }
}
// 配置类
@Component
@RefreshScope
public class DynamicConfig {
    @Value("${app.feature.enabled:false}")
    private boolean featureEnabled;
    @Value("${app.timeout:5000}")
    private int timeout;
    // getter方法
    public boolean isFeatureEnabled() {
        return featureEnabled;
    }
    public int getTimeout() {
        return timeout;
    }
}
// 使用示例
@RestController
public class ConfigController {
    @Autowired
    private DynamicConfig dynamicConfig;
    @GetMapping("/api/config")
    public String getConfig() {
        return "Feature: " + dynamicConfig.isFeatureEnabled() 
             + ", Timeout: " + dynamicConfig.getTimeout();
    }
    @PostMapping("/actuator/refresh")
    public String refreshConfig() {
        // 手动触发刷新
        return "Config refreshed";
    }
}

基于数据库的动态配置方案

自定义配置表设计

-- 创建配置表
CREATE TABLE system_config (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    config_key VARCHAR(100) UNIQUE NOT NULL,
    config_value VARCHAR(500),
    config_desc VARCHAR(255),
    version INT DEFAULT 1,
    create_time DATETIME,
    update_time DATETIME
);
-- 插入示例数据
INSERT INTO system_config (config_key, config_value, config_desc) VALUES
('app.feature.enabled', 'false', '功能开关'),
('app.timeout', '5000', '超时时间(ms)'),
('app.rate.limit', '100', '速率限制');

动态配置管理器

@Component
public class DynamicConfigManager {
    @Autowired
    private ConfigRepository configRepository;
    @Autowired
    private ApplicationContext applicationContext;
    // 本地缓存
    private final Map<String, String> configCache = new ConcurrentHashMap<>();
    @PostConstruct
    public void init() {
        loadAllConfigs();
    }
    // 加载所有配置到缓存
    public void loadAllConfigs() {
        List<SystemConfig> configs = configRepository.findAll();
        configs.forEach(config -> 
            configCache.put(config.getConfigKey(), config.getConfigValue())
        );
    }
    // 获取配置值
    public String getConfig(String key, String defaultValue) {
        return configCache.getOrDefault(key, defaultValue);
    }
    // 更新配置
    @Transactional
    public void updateConfig(String key, String value) {
        SystemConfig config = configRepository.findByConfigKey(key)
            .orElse(new SystemConfig());
        config.setConfigKey(key);
        config.setConfigValue(value);
        config.setVersion(config.getVersion() + 1);
        config.setUpdateTime(LocalDateTime.now());
        configRepository.save(config);
        // 更新缓存
        configCache.put(key, value);
        // 发送配置变更事件
        publishConfigChangeEvent(key, value);
    }
    // 发布配置变更事件
    private void publishConfigChangeEvent(String key, String value) {
        ConfigChangeEvent event = new ConfigChangeEvent(this, key, value);
        applicationContext.publishEvent(event);
    }
}
// 配置变更事件
public class ConfigChangeEvent extends ApplicationEvent {
    private final String configKey;
    private final String configValue;
    public ConfigChangeEvent(Object source, String configKey, String configValue) {
        super(source);
        this.configKey = configKey;
        this.configValue = configValue;
    }
    // getter方法
    public String getConfigKey() { return configKey; }
    public String getConfigValue() { return configValue; }
}
// 配置变更监听器
@Component
public class ConfigChangeListener {
    @EventListener
    public void handleConfigChange(ConfigChangeEvent event) {
        String key = event.getConfigKey();
        String value = event.getConfigValue();
        System.out.println("Config changed: " + key + " = " + value);
        // 根据不同key执行不同逻辑
        switch (key) {
            case "app.feature.enabled":
                handleFeatureToggle(value);
                break;
            case "app.timeout":
                handleTimeoutChange(value);
                break;
            default:
                break;
        }
    }
    private void handleFeatureToggle(String value) {
        boolean enabled = Boolean.parseBoolean(value);
        System.out.println("Feature toggle: " + (enabled ? "enabled" : "disabled"));
    }
    private void handleTimeoutChange(String value) {
        int timeout = Integer.parseInt(value);
        System.out.println("Timeout changed to: " + timeout + "ms");
    }
}

配置API控制器

@RestController
@RequestMapping("/api/config")
public class ConfigApiController {
    @Autowired
    private DynamicConfigManager configManager;
    // 获取所有配置
    @GetMapping
    public Map<String, String> getAllConfigs() {
        Map<String, String> configs = new HashMap<>();
        configs.put("feature.enabled", configManager.getConfig("app.feature.enabled", "false"));
        configs.put("timeout", configManager.getConfig("app.timeout", "5000"));
        return configs;
    }
    // 更新配置
    @PutMapping("/{key}")
    public ApiResponse updateConfig(@PathVariable String key, @RequestBody ConfigUpdateRequest request) {
        try {
            configManager.updateConfig(key, request.getValue());
            return ApiResponse.success("Config updated successfully");
        } catch (Exception e) {
            return ApiResponse.error("Failed to update config: " + e.getMessage());
        }
    }
    // 批量更新配置
    @PutMapping("/batch")
    public ApiResponse batchUpdate(@RequestBody Map<String, String> configs) {
        configs.forEach((key, value) -> {
            configManager.updateConfig(key, value);
        });
        return ApiResponse.success("Batch config updated");
    }
}

使用开源配置中心

Apollo配置中心集成

<!-- Maven依赖 -->
<dependency>
    <groupId>com.ctrip.framework.apollo</groupId>
    <artifactId>apollo-client</artifactId>
    <version>1.9.1</version>
</dependency>
// 1. 配置类
@Configuration
@EnableApolloConfig
public class ApolloConfig {
    @Value("${app.feature.enabled:false}")
    private boolean featureEnabled;
    // Apollo会自动刷新@Value注解的值
}
// 2. 监听配置变化
@Component
public class ConfigChangeMonitor {
    @Autowired
    private ConfigChangeListener listener;
    @ApolloConfigChangeListener
    private void onChange(ConfigChangeEvent changeEvent) {
        for (String key : changeEvent.changedKeys()) {
            ConfigChange change = changeEvent.getChange(key);
            System.out.println(String.format(
                "Config changed - key: %s, oldValue: %s, newValue: %s, changeType: %s",
                key, change.getOldValue(), change.getNewValue(), change.getChangeType()
            ));
        }
        // 如果配置变化,刷新bean
        listener.refreshConfig();
    }
}
// 3. 测试使用
@Service
public class FeatureService {
    @Autowired
    private ApolloConfig apolloConfig;
    public void executeFeature() {
        if (apolloConfig.isFeatureEnabled()) {
            // 新功能逻辑
            System.out.println("Executing new feature");
        } else {
            // 旧功能逻辑
            System.out.println("Executing old feature");
        }
    }
}

实战案例:动态线程池配置

@Component
public class DynamicThreadPoolManager {
    private ThreadPoolExecutor executor;
    @Value("${thread.pool.coreSize:10}")
    private int corePoolSize;
    @Value("${thread.pool.maxSize:20}")
    private int maxPoolSize;
    @Value("${thread.pool.queueCapacity:100}")
    private int queueCapacity;
    @Autowired
    private DynamicConfigManager configManager;
    @PostConstruct
    public void init() {
        // 初始化线程池
        executor = new ThreadPoolExecutor(
            corePoolSize,
            maxPoolSize,
            60L, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(queueCapacity),
            new ThreadPoolExecutor.CallerRunsPolicy()
        );
        // 注册配置变更监听
        configManager.registerConfigChangeListener("thread.pool.coreSize", this::updateCorePoolSize);
        configManager.registerConfigChangeListener("thread.pool.maxSize", this::updateMaxPoolSize);
    }
    // 动态更新核心线程数
    private void updateCorePoolSize(String value) {
        int newSize = Integer.parseInt(value);
        executor.setCorePoolSize(newSize);
        System.out.println("Core pool size updated to: " + newSize);
    }
    // 动态更新最大线程数
    private void updateMaxPoolSize(String value) {
        int newSize = Integer.parseInt(value);
        executor.setMaximumPoolSize(newSize);
        System.out.println("Max pool size updated to: " + newSize);
    }
    // 提交任务
    public Future<?> submit(Runnable task) {
        return executor.submit(task);
    }
    // 获取线程池状态
    public Map<String, Object> getPoolStatus() {
        Map<String, Object> status = new HashMap<>();
        status.put("corePoolSize", executor.getCorePoolSize());
        status.put("maxPoolSize", executor.getMaximumPoolSize());
        status.put("activeCount", executor.getActiveCount());
        status.put("completedTaskCount", executor.getCompletedTaskCount());
        status.put("queueSize", executor.getQueue().size());
        return status;
    }
}

实现Java动态配置的核心要点:

  1. 配置存储:选择文件、数据库或配置中心
  2. 配置刷新:支持动态刷新机制
  3. 缓存策略:使用本地缓存提升性能
  4. 事件通知:配置变更时通知相关组件
  5. 监控管理:提供配置查看和修改的API

根据项目规模选择合适方案:

  • 小型项目:Spring Cloud Config
  • 中型项目:数据库+缓存
  • 大型项目:Apollo/Nacos等专业配置中心

抱歉,评论功能暂时关闭!