一篇文章帶你從源碼解析 SpringBoot 中的靜態資源存放位置

一、源碼分析

“shift” 雙擊搜索 WebMvcAutoConfiguration ,進入找到資源的映射方法:

        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            if (!this.resourceProperties.isAddMappings()) {
                logger.debug("Default resource handling disabled");
            } else {
                if (!registry.hasMappingForPattern("/webjars/**")) {
                    ResourceHandlerRegistration registration = 
                    registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]
                    {"classpath:/META-INF/resources/webjars/"});
                    this.configureResourceCaching(registration);
                    this.customizeResourceHandlerRegistration(registration);
                }

                String staticPathPattern = this.webFluxProperties.getStaticPathPattern();
                if (!registry.hasMappingForPattern(staticPathPattern)) {
                    ResourceHandlerRegistration registration = 
                    registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(
                    this.resourceProperties.getStaticLocations());
                    this.configureResourceCaching(registration);
                    this.customizeResourceHandlerRegistration(registration);
                }
            }
        }
if (!registry.hasMappingForPattern("/webjars/**")) {
                    this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{
                    "classpath:/META-INF/resources/webjars/"}).
                    setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
                }

其中這個的意思是所有包含所有包含有/webjars/**的訪問路徑若沒有處理器處理的話都會去classpath:/META-INF/resources/webjars/這個目錄下尋找資源

往下走我們來看靜態路徑規則:
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
進入該方法:getStaticPathPattern()

public String getStaticPathPattern() {
        return this.staticPathPattern;
    }

繼續進入:this.staticPathPattern
在這裏插入圖片描述
所以這裏的意思就是你訪問的任何路徑如果是沒有處理器來處理的話,都會默認從這裏找訪問資源:
在這裏插入圖片描述
然後進入getStaticLocations()看看具體從哪些地方來獲取靜態資源:
在這裏插入圖片描述
進入發現:

  private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]
  {"classpath:/META-INF/resources/", "classpath:/resources/", 
  "classpath:/static/", "classpath:/public/"};
  
 this.staticLocations = CLASSPATH_RESOURCE_LOCATIONS;

這裏可以看到這裏一共返回來了四個放置靜態資源的位置,其中優先級也是這個順序:
(1)classpath:/META-INF/resources/
(2)classpath:/resources/
(3)classpath:/static/
(4)classpath:/public/

再回到:WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations()))
this.resourceProperties.getStaticLocations() 返回四個靜態資源位置到getResourceLocations,進入getResourceLocations方法查看:
在這裏插入圖片描述
這裏可以看出重新定義了 locations 並返回,而locations 將 傳來的 staticLocations 和這裏的 SERVLET_LOCATIONS 整合到了一塊返回

private static final String[] SERVLET_LOCATIONS = new String[]{"/"};

這裏的/表示的是webapp那個目錄
所以這裏一共返回來5個靜態資源的位置:有順序區分
(1)classpath:/META-INF/resources/
(2)classpath:/resources/
(3)classpath:/static/
(4)classpath:/public/
(5)/

二、示例演示

已經知道靜態資源訪問的先後次序:
在這裏插入圖片描述
在這裏插入圖片描述
可以看到 static 下的test.html 優於 public 下的先執行

三、自定義資源訪問位置

1. 通過 application.properties 配置

第一部分我們已經分析了,獲取資源訪問的位置就是從這裏獲取的,可以看到這裏的前綴spring.resources,所以我們可以在 application.properties 中重新給 staticLocations 這個屬性賦值即可。
在這裏插入圖片描述
在這裏插入圖片描述
訪問成功:
在這裏插入圖片描述

2. Java 代碼重寫 addResourceHandlers

也就是不用自帶的 addResourceHandlers 資源映射方法,我們自己重新實現一個該方法,將需要的資源映射路徑加入進去即可

@Configuration
public class WebMvcConfig implements WebMvcConfigurer{
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("classpath:/yolo/");
    }
}

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章