在SpringBoot中,如果我們是從https://start.spring.io這個網站上建立的項目,或者使用IntelliJIDEA中的SpringBoot初始化工具建立的項目,預設的靜态資源都會存在resources/static目錄下,很多小夥伴也知道靜态資源隻要放到這個目錄下,就可以直接通路。那麼,除了這裡還有沒有其他可以放靜态資源的位置呢?為什麼放在這裡就能直接通路了呢?本篇文章就帶領大家了解一下SpringBoot架構中的靜态資源配置。
一、靜态資源可存放位置
首先,在SpringBoot中,預設情況下,一共有5個位置可以放靜态資源,五個路徑分别是如下5個:
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/
/
前四個目錄好了解,分别對應了resources目錄下不同的目錄,第5個/是啥意思呢?
我們知道,在SpringBoot項目中,預設是沒有webapp這個目錄的,當然我們也可以自己添加(例如在需要使用JSP的時候),這裡第5個/其實就是表示webapp目錄中的靜态資源也不被攔截。如果同一個檔案分别出現在五個目錄下,那麼優先級也是按照上面列出的順序。
不過,雖然有5個存儲目錄,除了第5個用的比較少之外,其他四個,系統均預設建立了classpath:/static/。
正常情況下,我們隻需要将我們的靜态資源放到這個目錄下即可,也不需要額外去建立其他靜态資源目錄。
舉例說明:
例如在classpath:/static/目錄下放了一張名為1.png的圖檔,那麼我的通路路徑是:http://localhost:8080/1.png。
這裡大家注意,請求位址中并不需要static這層路徑,如果加上了static反而多此一舉,報404錯誤。
很多人會覺得奇怪,為什麼不需要添加static呢?資源明明放在static目錄下。其實這個效果很好實作,例如在SSM架構整合配置中,我們的靜态資源攔截配置如果是下面這樣:
<mvc:resources mapping="/**" location="/static/"/>
如果我們是這樣配置的話,請求位址如果是 http://localhost:8080/1.png。
實際上系統會去 /static/1.png 目錄下查找相關的檔案。是以我們理所當然的猜測,在SpringBoot中可能也是類似的配置。接下來我們通過解讀SpringBoot源碼,來看下它是如何實作的。
我們知道SpringBoot項目啟動類是入口,在項目的pom.xml中引入需要的場景啟動器後,根據自動配置原理,SpringBoot架構會盡可能為我們比對并加載對應所需的所有的類到Spring容器中,以便于開發時我們可以随時從容器中擷取到對應的元件對象。
在spring.factories檔案中,在Auto Configure自動配置這一欄有一個配置類,叫做WebMvcAutoConfiguration。
在這個類中我們可以看到有關SpringMVC自動化配置的相關内容。
在WebMvcAutoConfiguration類中,我們檢視addResourceHandlers()方法,斷點如下:
其中,this.mvcProperties.getStaticPathPattern()方法對應的值是/**, this.resourceProperties.getStaticLocations()方法傳回了四個位置,分别是:
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/
然後在getResourceLocations方法中,又添加了/,是以這裡傳回值一共有5個。其中,/ 表示webapp目錄,即webapp中的靜态檔案也可以直接通路。
靜态資源的比對路徑按照定義路徑優先級依次降低。
是以這裡的配置和我們前面提到的如出一轍。這樣大夥就知道了為什麼Spring Boot中支援5個靜态資源位置,同時也明白了為什麼靜态資源請求路徑中不需要/static,因為在路徑映射中已經自動的添加上了/static了。
二、自定義配置
上述我們說的是系統預設配置,如果我們并不想将資源放在系統預設的這五個位置上,也可以自定義靜态資源位置和映射,自定義的方式也有兩種,可以通過application.properties來定義,也可以在Java代碼中來定義,下面我們分别來看。
1.1通過application.properties配置
這種方式比較簡單,我們可以直接配置指定:
spring.resources.static-locations=classpath:/
spring.mvc.static-path-pattern=/**
第一行配置表示定義資源位置,第二行配置表示定義請求URL規則。
以上文的配置為例,如果我們這樣定義了,表示可以将靜态資源放在resources目錄下的任意地方,我們通路的時候當然也需要寫完整的路徑,例如在resources/static目錄下有一張名為1.png的圖檔,那麼通路路徑就是http://localhost:8080/static/1.png。注意此時的static不能省略。
1.2通過Java代碼完成
使用Java代碼完成自定義靜态資源配置。
@Configuration // 該注解表示目前類是一個配置類
public class WebMVCConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
}
}
總結
通過上面的講解,相信大家對SpringBoot中靜态資源的位置有一定了解了。在這裡需要強調的是,有很多朋友用了Thymeleaf之後,會将靜态資源也放在resources/templates目錄下,注意,這裡templates目錄并不是靜态資源目錄,它隻是一個放頁面模闆的位置,模闆雖然字尾也為 .html,其實它并不是靜态資源。