基于SpringBoot+Docker實現(xiàn)可掛載可熱更新的config.json
一、背景:為什么 jar 內(nèi)的 config.json 不能被覆蓋?
很多人遇到這樣的場景:
- 前端請求
GET /config.json - 想通過 Docker 掛載一份外部
config.json到容器里覆蓋 jar 里的那份 - 結(jié)果發(fā)現(xiàn)改了也不生效 → 還是讀到打包進 jar 的老版本
根本原因:
Spring Boot 不會自動替換 jar 內(nèi)部的靜態(tài)資源文件,掛載的靜態(tài)資源只是在查找路徑里排在前面而已。
換句話說:
文件如果在 jar 里,通過 classpath 加載的優(yōu)先級并不因為掛載而被覆蓋(實際查找路徑可能不同)。
二、Spring Boot 靜態(tài)資源加載機制
在 Spring Boot 里,靜態(tài)資源是這樣被查找的:
# Spring Boot 2.4+ 使用這個 spring.web.resources.static-locations=file:/app/static/, classpath:/static/ # Spring Boot 2.3- 使用這個 spring.resources.static-locations=file:/app/static/, classpath:/static/
這個配置表示:
| 優(yōu)先級 | 資源位置 |
|---|---|
| 第一 | 外部目錄 file:/app/static/ |
| 第二 | jar 內(nèi) classpath:/static/ |
注意:這是查找順序,不是覆蓋機制。
三、解決方案結(jié)構(gòu)
為了做到:
? Docker 容器掛載的 config.json 可覆蓋
? 修改后立即生效(無重啟,無緩存)
? 支持 /config.json 和 /wvp/config.json 兩種訪問路徑
我們的整體方案是:
前端請求 /config.json 或 /wvp/config.json → 后端 Controller 先嘗試讀取 容器內(nèi) /app/config/config.json → 如果存在直接返回 → 如果不存在再 fallback 到 classpath:/static/config.json
同時設(shè)置返回頭 Cache-Control: no-store 避免瀏覽器緩存舊配置。
四、核心實現(xiàn):優(yōu)先讀外部文件
在你的 Controller 里寫如下邏輯:
@RestController
public class WvpIndexController {
private static final String EXTERNAL_PATH = "/app/config/config.json";
private static final String CLASSPATH_PATH = "classpath:/static/config.json";
@GetMapping({"/config.json", "/wvp/config.json"})
public ResponseEntity<Resource> getConfig(HttpServletResponse response) {
Resource resource;
// 1) 優(yōu)先嘗試讀取外部掛載文件
File external = new File(EXTERNAL_PATH);
if (external.exists() && external.isFile()) {
resource = new FileSystemResource(external);
} else {
// 2) 不存在則 fallback 到內(nèi)置 classpath
resource = new ClassPathResource("static/config.json");
}
// 設(shè)置不緩存
response.setHeader("Cache-Control", "no-store");
return ResponseEntity.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(resource);
}
}
五、完整 Dockerfile 示例
FROM openjdk:17-jdk-alpine WORKDIR /app COPY wvp.jar /app/wvp.jar COPY static /app/static # 靜態(tài)資源 fallback EXPOSE 8080 ENTRYPOINT ["java", \ "-Dspring.web.resources.static-locations=file:/app/static/,classpath:/static/", \ "-Dspring.resources.static-locations=file:/app/static/,classpath:/static/", \ "-jar", "wvp.jar"]
六、總結(jié)
| 方案 | 是否可掛載覆蓋 | 是否熱更新 | 是否兼容多個路徑 |
|---|---|---|---|
| 只依賴 Spring Boot 靜態(tài)資源 | ? | ? | ? |
| 加上后端優(yōu)先邏輯 | ? | ? | ? |
推薦方案:后端優(yōu)先讀取外部掛載文件 + fallback classpath + no-cache
這樣你只要:
docker-compose up -d
然后在宿主機改 config.json,前端刷新立即生效。
以上就是基于SpringBoot+Docker實現(xiàn)可掛載可熱更新的config.json的詳細內(nèi)容,更多關(guān)于SpringBoot Docker可掛載可熱更新config.json的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Mybatis千萬級數(shù)據(jù)查詢的解決方式,避免OOM問題
這篇文章主要介紹了Mybatis千萬級數(shù)據(jù)查詢的解決方式,避免OOM問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01
Java中基于maven實現(xiàn)zxing二維碼功能
這篇文章主要介紹了Java中基于maven實現(xiàn)zxing二維碼功能,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-02-02
Java音頻處理之音頻流轉(zhuǎn)音頻文件和獲取音頻播放時長詳解
這篇文章主要為大家詳細介紹了如何使用Java實現(xiàn)音頻流轉(zhuǎn)音頻文件和獲取音頻播放時長功能,文中的示例代碼簡潔易懂,有需要的小伙伴可以了解下2025-07-07
ObjectInputStream 和 ObjectOutputStream 介紹_動力節(jié)點Java學(xué)院整理
ObjectInputStream 和 ObjectOutputStream 的作用是,對基本數(shù)據(jù)和對象進行序列化操作支持。本文給大家詳細介紹了ObjectInputStream 和 ObjectOutputStream的相關(guān)知識,感興趣的朋友一起學(xué)習(xí)吧2017-05-05
java類訪問權(quán)限與成員訪問權(quán)限解析
這篇文章主要針對java類訪問權(quán)限與成員訪問權(quán)限進行解析,對類與成員訪問權(quán)限進行驗證,感興趣的小伙伴們可以參考一下2016-02-02
springboot+maven快速構(gòu)建項目的示例代碼
本篇文章主要介紹了springboot+maven快速構(gòu)建項目的示例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-08-08
MybatisPlus中@TableLogic注解的使用實現(xiàn)
@TableLogic注解是MyBatis-Plus框架中用于處理邏輯刪除的注解,邏輯刪除是一種常見的刪除策略,其中并不真正刪除數(shù)據(jù)記錄,而是通過修改某個標(biāo)記字段的值來表示記錄已經(jīng)被刪除,方便以后恢復(fù)或者審計,感興趣的可以了解一下2025-10-10

