在學習springboot的過程當中,發現沒法引用靜態資源。我使用的是springboot2.2.1版本。html
追溯源碼,終於解決。並記錄下解決思路。web
首先得知道springboot默認加載得資源路徑是什麼。spring
首先咱們看WebMvcAutoConfiguration這個類。裏面有一個方法叫作addResourceHandlers()json
@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)); } //靜態資源文件夾映射 String staticPathPattern = this.mvcProperties.getStaticPathPattern(); if (!registry.hasMappingForPattern(staticPathPattern)) { customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern) .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations())) .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl)); } } }
首先springboot會將咱們classpath:/META-INF/resources/webjars/路徑下的文件映射爲/webjars/**springboot
而後再一個if判斷進行靜態資源文件夾映射,首先判斷咱們是否以使用 "/**" 作映射mvc
若是沒有,則將"/**" 訪問當前項目的任何資源,都去(以下靜態資源的文件夾)找映射app
"classpath:/META‐INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/" "/":當前項目的根路徑
什麼意思呢?舉一個例子,就是說默認狀況下咱們假如咱們調用 http://localhost:8080/a.jsonide
Springboot就會從上面得這幾個路徑下去找a.json這個文件。學習
源碼也是如同猜測得這樣,那爲何個人代碼中,直接訪問靜態資源卻沒法作映射呢?this
咱們再仔細看看WebMvcAutoConfiguration這個類。在其頭上有一個這個註解:
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
臥槽,瞬間恍然大悟。在我得配置文件中:
@Configuration public class MyMVCConfig extends WebMvcConfigurationSupport{ ... }
繼承了WebMvcConfigurationSupport這個類,使得springboot的自動裝配失效了。由於@ConditionalOnMissingBean這個註解得做用就是,當容器中不存在這個類,以下得代碼纔有做用。
爲何會這樣設計呢?
由於有時候咱們得項目並不但願springboot給咱們自動裝配。但願徹底由咱們本身來配置本身來掌握。
要想達到這個效果,springboot給咱們提供了一個更爲簡潔得方式。
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented @Import(DelegatingWebMvcConfiguration.class) public @interface EnableWebMvc { }
@EnableWebMvc註解會導入DelegatingWebMvcConfiguration.clss 而DelegatingWebMvcConfiguration又繼承了WebMvcConfigurationSupport
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
因此當咱們加上@EnableWebMvc也會有一樣得效果且簡潔。
springboot固然也支持咱們個性化得指定映射路徑,我總結了以下幾個方式:
@Configuration public class MyMVCConfig extends WebMvcConfigurationSupport{ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); } }
上面的意思就是:將全部/static下得文件所有映射到/static/**
在application.properties文件中加上以下配置項
spring.mvc.static-path-pattern=/** spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,\ classpath:/static/,classpath:/public/
spring.mvc.static-path-pattern=/**:表示全部的訪問都通過靜態資源路徑;
spring.resources.static-locations:在這裏配置靜態資源路徑。
原文出處:https://www.cnblogs.com/zhxiansheng/p/11933482.html