springboot2版本無(wú)法加載靜態(tài)資源問(wèn)題解決
前言
在學(xué)習(xí)springboot的過(guò)程中,發(fā)現(xiàn)無(wú)法引用靜態(tài)資源。我使用的是springboot2.2.1版本。
追溯源碼,終于解決。并記錄下解決思路。
默認(rèn)加載路徑
首先得知道springboot默認(rèn)加載得資源路徑是什么。
首先我們看WebMvcAutoConfiguration這個(gè)類(lèi)。里面有一個(gè)方法叫做addResourceHandlers()
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
//所有 /webjars/** ,都去 classpath:/META-INF/resources/webjars/ 找資源
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
//靜態(tài)資源文件夾映射
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
.addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
}
}
首先springboot會(huì)將我們classpath:/META-INF/resources/webjars/路徑下的文件映射為/webjars/**
然后再一個(gè)if判斷進(jìn)行靜態(tài)資源文件夾映射,首先判斷我們是否以使用 "/**" 做映射
如果沒(méi)有,則將"/**" 訪(fǎng)問(wèn)當(dāng)前項(xiàng)目的任何資源,都去(如下靜態(tài)資源的文件夾)找映射
"classpath:/META‐INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/" "/":當(dāng)前項(xiàng)目的根路徑
什么意思呢?舉一個(gè)例子,就是說(shuō)默認(rèn)情況下我們假如我們調(diào)用 http://localhost:8080/a.json
Springboot就會(huì)從上面得這幾個(gè)路徑下去找a.json這個(gè)文件。
問(wèn)題所在
源碼也是如同猜想得這樣,那為什么我的代碼中,直接訪(fǎng)問(wèn)靜態(tài)資源卻無(wú)法做映射呢?
我們?cè)僮屑?xì)看看WebMvcAutoConfiguration這個(gè)類(lèi)。在其頭上有一個(gè)這個(gè)注解:
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
臥槽,瞬間恍然大悟。在我得配置文件中:
@Configuration
public class MyMVCConfig extends WebMvcConfigurationSupport{
...
}
繼承了WebMvcConfigurationSupport這個(gè)類(lèi),使得springboot的自動(dòng)裝配失效了。因?yàn)锧ConditionalOnMissingBean這個(gè)注解得作用就是,當(dāng)容器中不存在這個(gè)類(lèi),如下得代碼才有作用。
為什么會(huì)這樣設(shè)計(jì)呢?
因?yàn)橛袝r(shí)候我們得項(xiàng)目并不希望springboot給我們自動(dòng)裝配。希望完全由我們自己來(lái)配置自己來(lái)掌握。
要想達(dá)到這個(gè)效果,springboot給我們提供了一個(gè)更為簡(jiǎn)潔得方式。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}
@EnableWebMvc注解會(huì)導(dǎo)入DelegatingWebMvcConfiguration.clss
而DelegatingWebMvcConfiguration又繼承了WebMvcConfigurationSupport
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
所以當(dāng)我們加上@EnableWebMvc也會(huì)有同樣得效果且簡(jiǎn)潔。
自定義配置資源映射
springboot當(dāng)然也支持我們個(gè)性化得指定映射路徑,我總結(jié)了如下幾個(gè)方式:
配置類(lèi)
@Configuration
public class MyMVCConfig extends WebMvcConfigurationSupport{
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
}
}
上面的意思就是:將所有/static下得文件全部映射到/static/**
配置項(xiàng)
在application.properties文件中加上如下配置項(xiàng)
spring.mvc.static-path-pattern=/** spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/, classpath:/static/,classpath:/public/
spring.mvc.static-path-pattern=/**:表示所有的訪(fǎng)問(wèn)都經(jīng)過(guò)靜態(tài)資源路徑;
spring.resources.static-locations:在這里配置靜態(tài)資源路徑。
相關(guān)文章
Spring中@Autowired和@Resource注解的使用區(qū)別詳解
這篇文章主要介紹了Spring中@Autowired和@Resource注解的使用區(qū)別詳解,@Autowired默認(rèn)根據(jù)type進(jìn)行注入,找到與指定類(lèi)型兼容的?Bean?并進(jìn)行注入,如果無(wú)法通過(guò)type匹配到對(duì)應(yīng)的?Bean?的話(huà),會(huì)根據(jù)name進(jìn)行匹配,如果都匹配不到則拋出異常,需要的朋友可以參考下2023-11-11
ElasticSearch學(xué)習(xí)之多條件組合查詢(xún)驗(yàn)證及示例分析
這篇文章主要為大家介紹了ElasticSearch 多條件組合查詢(xún)驗(yàn)證及示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
mybatis多個(gè)接口參數(shù)的注解使用方式(@Param)
這篇文章主要介紹了mybatis多個(gè)接口參數(shù)的注解使用方式(@Param),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-10-10
Intellij IDEA中一次性折疊所有Java代碼的快捷鍵設(shè)置
這篇文章主要介紹了Intellij IDEA中一次性折疊所有Java代碼的快捷鍵設(shè)置,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
如何在Mac上安裝并配置JDK環(huán)境變量詳細(xì)步驟
這篇文章主要介紹了如何在Mac上安裝并配置JDK環(huán)境變量詳細(xì)步驟,包括下載JDK、安裝JDK、配置環(huán)境變量、驗(yàn)證JDK配置以及可選地設(shè)置PowerShell為默認(rèn)終端,需要的朋友可以參考下2025-04-04
華為技術(shù)專(zhuān)家講解JVM內(nèi)存模型(收藏)
這篇文章主要介紹了華為技術(shù)專(zhuān)家講解JVM內(nèi)存模型(收藏)的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),具有一定的收藏借鑒價(jià)值,需要的朋友可以參考下2021-05-05
SpringCloud Feign傳遞HttpServletRequest對(duì)象流程
HttpServletRequest接口的對(duì)象代表客戶(hù)端的請(qǐng)求,當(dāng)客戶(hù)端通過(guò)HTTP協(xié)議訪(fǎng)問(wèn)Tomcat服務(wù)器時(shí),HTTP請(qǐng)求中的所有信息都封裝在HttpServletRequest接口的對(duì)象中,這篇文章介紹了Feign傳遞HttpServletRequest對(duì)象的流程,感興趣的同學(xué)可以參考下文2023-05-05

