springboot2版本无法加载静态资源问题解决

网友投稿 387 2022-12-21


springboot2版本无法加载静态资源问题解决

前言

在学习springboot的过程中,发现无法引用静态资源。我使用的是springboot2.2.1版本。

追溯源码,终于解决。并记录下解决思路。

默认加载路径

首先得知道springboot默认加载得资源路径是什么。

首先我们看WebMvcAutoConfiguration这个类。里面有一个方法叫做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));

}

//静态资源文件夹映射

String staticPathPattern = this.mvcProperties.getStaticPathPattern();

if (!registry.hasMappingForPattern(staticPathPattern)) {

customizeResourceHandlerRegistration(registry.ahttp://ddResourceHandler(staticPathPattern)

.addResourceLocations(getResourceLocations(this.rehttp://sourceProperties.getStaticLocations()))

.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));

}

}

}

首先springboot会将我们classpath:/META-INF/resources/webjars/路径下的文件映射为/webjars/**

然后再一个if判断进行静态资源文件夹映射,首先判断我们是否以使用 "/**" 做映射

如果没有,则将"/**" 访问当前项目的任何资源,都去(如下静态资源的文件夹)找映射

"classpath:/META‐INF/resources/",

"classpath:/resources/",

"classpath:/static/",

"classpath:/public/"

"/":当前项目的根路径

什么意思呢?举一个例子,就是说默认情况下我们假如我们调用 http://localhost:8080/a.json

Springboot就会从上面得这几个路径下去找a.json这个文件。

问题所在

源码也是如同猜想得这样,那为什么我的代码中,直接访问静态资源却无法做映射呢?

我们再仔细看看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:在这里配置静态资源路径。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Spring Bean初始化及销毁多种实现方式
下一篇:Log4j新手快速入门教程
相关文章

 发表评论

暂时没有评论,来抢沙发吧~