一、源碼分析
“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/");
}
}