Spring Boot2.0實(shí)現(xiàn)靜態(tài)資源版本控制詳解
寫在最前面
猶記畢業(yè)第一年時(shí),公司每次發(fā)布完成后,都會(huì)在一個(gè)群里通知【版本更新,各部門清理緩存,有問題及時(shí)反饋】之類的話。歸根結(jié)底就是資源緩存的問題,瀏覽器會(huì)將請(qǐng)求到的靜態(tài)資源,如JS、CSS等文件緩存到用戶本地,當(dāng)用戶再次訪問時(shí)就不需要再次請(qǐng)求這些資源了,以此也是提升了用戶體驗(yàn)。但是也正是因?yàn)檫@些資源緩存,導(dǎo)致客戶端的靜態(tài)文件往往不是當(dāng)前最新版本。后來有同事增加了時(shí)間戳、隨機(jī)數(shù)等,確實(shí)這也解決了客戶端緩存的問題,但是卻又帶來了新的麻煩,導(dǎo)致每次訪問都要請(qǐng)求服務(wù)器,無形中增加了服務(wù)器的壓力。
那么有什么辦法可以讓客戶端當(dāng)需要更新時(shí)才去請(qǐng)求,不需更新就不請(qǐng)求嗎?當(dāng)然有,實(shí)現(xiàn)方式很多種,像前端實(shí)現(xiàn),webjars實(shí)現(xiàn)等都可以,但是麻煩還是麻煩,太燒腦。介紹一種Spring自身提供的方式,也是我目前所應(yīng)用的方式,ResourceUrlProvider。
ResourceUrlProvider的實(shí)現(xiàn)效果有兩種,大家可以在后文中看到。下面話不多說了,來一起看看詳細(xì)的介紹吧
第一種、MD5實(shí)現(xiàn)
首先在application.yml或者application.properties中增加配置文件
spring: resources: chain: strategy: content: enabled: true paths: /**
其次,如果您恰巧和我一樣使用Thymeleaf作為模板引擎,則可以和我一樣使用@bean語法直接從模板訪問ResourceUrlProvider bean。
<script th:src="${@mvcResourceUrlProvider.getForLookupPath('/mods/admin/login.js')}"></script>
如果您使用的模板引擎無法直接訪問Spring bean,則可以將ResourceUrlProvider 添加到Spring中。使用ControllerAdvice,代碼如下:
@ControllerAdvice public class ControllerConfig { @Autowired ResourceUrlProvider resourceUrlProvider; @ModelAttribute("urls") public ResourceUrlProvider urls() { return this.resourceUrlProvider; } }
然后在頁面上通過下述代碼引用:
<script th:src="${urls.getForLookupPath('/mods/admin/login.js')}"></script>
此方法應(yīng)適用于支持方法調(diào)用的所有模板引擎。
下面我們來看看具體的實(shí)現(xiàn)效果吧,前臺(tái)訪問后html頁面顯示為:
<script src="/mods/admin/login-96d770c87905659930c9786eaa08d710.js"></script>
注意:如果你的js文件沒有修改,或者修改沒重啟,MD5的值可能不會(huì)改變,當(dāng)你重啟服務(wù)后你會(huì)看到你修改過后的文件MD5也隨之改變了。
簡單看了下源代碼,MD5的計(jì)算是通過 ContentVersionStrategy 這個(gè)類實(shí)現(xiàn)的。此VersionStrategy實(shí)現(xiàn)根據(jù)資源的內(nèi)容計(jì)算MD5哈希值,并將其附加到文件名后面,也就是你不改變內(nèi)容MD5值是不會(huì)變的哦,一度讓我以為這種方法有BUG(。•ˇ‸ˇ•。)。
第二種、版本號(hào)實(shí)現(xiàn)
同樣在application.yml或者application.properties中增加配置文件
spring: resources: chain: strategy: fixed: enabled: true paths: /mods/admin/*.js version: 20181128
后續(xù)操作同上,此時(shí)我們看下頁面顯示的效果:
<script src="/20181128/mods/admin/login.js"></script>
在文件路徑的最前面增加了版本號(hào),當(dāng)我們每次修改只需要更新版本號(hào)的設(shè)置,客戶端就會(huì)自動(dòng)請(qǐng)求最新的數(shù)據(jù)了。
同樣的看了下此VersionStrategy的實(shí)現(xiàn)是FixedVersionStrategy類,來使固定版本字符串作為資源路徑的前綴。
總結(jié)
相比其他方式的靜態(tài)資源控制,這種方式是我目前發(fā)現(xiàn)最簡便的了,尤其是在SpringBoot項(xiàng)目中的使用。在這兩種方式中,我更傾向于方法一的MD5方式,可以讓我們不必太過于關(guān)注靜態(tài)資源問題。當(dāng)然上述講的兩個(gè)實(shí)現(xiàn)類,在傳統(tǒng)SpringMVC項(xiàng)目中也是有的,所以傳統(tǒng)項(xiàng)目也是可以使用的,具體的使用方法大家可以研究研究。
好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
- Spring Boot 靜態(tài)資源處理方式
- Spring Boot使用Value注解給靜態(tài)變量賦值的方法
- springboot操作靜態(tài)資源文件的方法
- Spring Boot 從靜態(tài)json文件中讀取數(shù)據(jù)所需字段
- Spring boot工具類靜態(tài)屬性注入及多環(huán)境配置詳解
- spring boot靜態(tài)變量注入配置文件詳解
- Spring Boot Web 靜態(tài)文件緩存處理的方法
- 在SpringBoot中靜態(tài)資源訪問方法
- SpringBoot靜態(tài)資源css,js,img配置方案
- Spring Boot 靜態(tài)資源處理
相關(guān)文章
springboot項(xiàng)目中controller層與前端的參數(shù)傳遞方式
這篇文章主要介紹了springboot項(xiàng)目中controller層與前端的參數(shù)傳遞方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10Spring cloud Feign 深度學(xué)習(xí)與應(yīng)用詳解
這篇文章主要介紹了Spring cloud Feign 深度學(xué)習(xí)與應(yīng)用詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-06-06Java中if...else語句使用的學(xué)習(xí)教程
這篇文章主要介紹了Java中if...else語句使用的學(xué)習(xí)教程,是Java入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-11-11idea向System.getenv()添加系統(tǒng)環(huán)境變量的操作
這篇文章主要介紹了idea向System.getenv()添加系統(tǒng)環(huán)境變量的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06Java編程用棧來求解漢諾塔問題的代碼實(shí)例(非遞歸)
這篇文章主要介紹了Java編程用棧來求解漢諾塔問題的代碼實(shí)例(非遞歸),具有一定參考價(jià)值,這里給大家分享下,供朋友們參考。2017-10-10Mybatis的類型轉(zhuǎn)換接口TypeHandler
這篇文章主要介紹了Mybatis的類型轉(zhuǎn)換接口TypeHandler,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-08-08Spring內(nèi)置定時(shí)任務(wù)調(diào)度@Scheduled使用詳解
這篇文章主要介紹了Spring內(nèi)置定時(shí)任務(wù)調(diào)度@Scheduled使用詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12