关于springboot2.*版本没法加载静态资源

前言

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

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

默认加载路径

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

首先咱们看WebMvcAutoConfiguration这个类。里面有一个方法叫作addResourceHandlers()springboot

@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/**mvc

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

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

"classpath:/META‐INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/"
"/":当前项目的根路径

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

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

问题所在

源码也是如同猜测得这样,那为何个人代码中,直接访问静态资源却没法作映射呢?spa

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

相关文章
相关标签/搜索