Spring Boot 2.1.4无需Config Server刷新外部application-optional.properties
两种方案实现外部
application-optional.properties的配置刷新(Spring Boot 2.1.4.RELEASE) 针对你的生产环境需求——不想大规模改动应用,只刷新外部的application-optional.properties,我整理了两种可行方案:
一、借助Spring Config Server实现(最小侵入式改动)
你不用把所有应用都接入Config Server的全量配置管理,只需要利用它的刷新能力做局部适配,改动非常小:
- 添加必要依赖:在你的pom.xml里引入两个核心依赖,版本和Spring Boot 2.1.4.RELEASE匹配(对应Spring Cloud Greenwich.SR1版本):
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> <version>Greenwich.SR1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> - 配置指向Config Server:在现有应用的内部配置文件(比如
application.properties)里加几行配置,只拉取你需要的application-optional配置:# 你的Config Server地址 spring.cloud.config.uri=http://your-config-server-address:port # 指定要拉取的配置文件名(对应Config Server上的application-optional.properties) spring.cloud.config.name=application-optional # 暴露actuator的刷新端点 management.endpoints.web.exposure.include=refresh - 标记需要刷新的配置类:在读取
application-optional.properties配置的类上加上@RefreshScope注解,这样触发刷新时,这个类的配置会重新加载:@Configuration @PropertySource("file:/path/to/your/external/application-optional.properties") // 替换成你的外部文件路径 @RefreshScope public class OptionalConfig { @Value("${your.custom.property}") private String yourProperty; // getter & setter 方法 } - 触发刷新:当Config Server上的
application-optional.properties更新后,调用应用的actuator端点就能完成刷新:
整个过程只加了依赖、几行配置和一个注解,完全不会影响现有生产应用的核心逻辑。POST http://your-app-url:port/actuator/refresh
二、不使用Config Server,纯Spring代码实现
如果不想引入Config Server,自己写代码也能搞定,核心是监听外部文件的变化并重新加载配置:
- 自定义配置加载与监听类:创建一个类负责加载外部配置文件,同时监听文件修改事件,触发配置刷新:
@Configuration public class OptionalConfigWatcher { private static final String EXTERNAL_CONFIG_PATH = "/your/external/path/application-optional.properties"; private final Properties optionalProps = new Properties(); private final File configFile = new File(EXTERNAL_CONFIG_PATH); @PostConstruct public void init() throws IOException { // 初始化加载配置 reloadConfig(); // 启动文件监听 startWatchingFile(); } private void reloadConfig() throws IOException { try (InputStream inputStream = new FileInputStream(configFile)) { optionalProps.load(inputStream); } } private void startWatchingFile() { // 用Spring自带的FileSystemWatcher监听文件变化 FileSystemWatcher watcher = new FileSystemWatcher(true); watcher.addSourceDirectory(configFile.getParentFile()); watcher.addListener(event -> { if (event.getFile().getName().equals(configFile.getName())) { try { reloadConfig(); // 刷新带有@RefreshScope的bean refreshScopedBeans(); } catch (IOException e) { // 这里可以根据你的生产需求加日志或告警 e.printStackTrace(); } } }); watcher.start(); } private void refreshScopedBeans() { ApplicationContext context = SpringApplication.getApplicationContext(); if (context instanceof ConfigurableApplicationContext) { ConfigurableApplicationContext configurableContext = (ConfigurableApplicationContext) context; // 销毁并重建@RefreshScope注解的bean configurableContext.getBeanFactory().destroyScopedBean(RefreshScope.class.getSimpleName()); configurableContext.refresh(); } } // 提供获取配置的方法给其他bean调用 public String getOptionalProperty(String key) { return optionalProps.getProperty(key); } } - 在业务类中使用:在需要读取该配置的业务类里注入这个监听类,同时加上
@RefreshScope确保bean能感知配置变化:@Service @RefreshScope public class YourBusinessService { @Autowired private OptionalConfigWatcher configWatcher; public void doBusinessLogic() { String configValue = configWatcher.getOptionalProperty("your.custom.property"); // 业务逻辑处理 } } - 注意事项:
- 要确保应用对外部配置文件有读取权限
- 如果
FileSystemWatcher在你的版本里有问题,可以替换成Apache Commons IO的FileAlterationObserver来实现文件监听 - 刷新上下文时,尽量只刷新和该配置相关的bean,避免影响其他核心业务组件
两种方案都不需要触动application.properties,完全聚焦在application-optional.properties的刷新上,适配你的生产环境需求。
内容的提问来源于stack exchange,提问作者Nayak
相关产品推荐
相关产品推荐

