SpringBoot-Web开发之静态资源管理
静态资源访问
- 静态资源规则源码(2.3.4.RELEASE版本)org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter
public void addResourceHandlers(ResourceHandlerRegistry registry) {//控制静态资源的访问是否生效,默认为false//配置文件中配置 spring: resources: add-mappings: true/false if (!this.resourceProperties.isAddMappings()) {logger.debug("Default resource handling disabled");} else {//静态资源存放的时间Duration cachePeriod = this.resourceProperties.getCache().getPeriod();CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();//webjars的规则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));}//控制静态资源访问路径前缀,默认是/**//配置文件 spring: mvc: static-path-pattern: 自定义路径(如:/res/**)String staticPathPattern = this.mvcProperties.getStaticPathPattern();if (!registry.hasMappingForPattern(staticPathPattern)) {this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern})//对应静态资源映射的默认位置.addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));}}
}
1. 静态资源目录访问
- 默认情况下,Spring Boot 从类路径src/main/resources中的以下目录获取资源
- classpath:/META-INF/resources/
- classpath:/resources/
- classpath:/static/
- /META-INF/resources目录
- ServletContext的根目录提供静态内容

- 优先级顺序为:META-INF/resources > resources > static > public
- 可以通过使用Spring MVC的ResourceHttpRequestHandler,添加自定义的WebMvcConfigurerAdapter并覆写addResourceHandlers方法来加载静态文件
@Configuration
public class MyConfiguration extends WebMvcConfigurerAdapter {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {//作用同配置文件registry.addResourceHandler("/res/**").addResourceLocations("classpath:/res/");//可以指定磁盘绝对路径,路径写法需要加上file://registry.addResourceHandler("/res/**")// .addResourceLocations("file:D:/SpringBoot/");super.addResourceHandlers(registry);}
}
2. 静态映射/**
- 请求进来,先去找Controller看能不能处理。不能处理的所有请求都交给静态资源处理器。静态资源也找不到则响应404页面
- /**表示任意层级的路径,这个原理可以从两个角度理解
- 角度一:所有符合要求的静态资源都被处理映射为"/"下的请求
- 角度二:静态资源处理器会拦截"/"下的所有的请求。
3. 配置改变默认路径
- static-locations:自定义配置静态资源所在路径
- 新版本已经不再支持 resources: static-locations: [classpath:/haha/]
- 可以替换为 web: resources: static-locations: classpath:/haha
- static-path-pattern:自定义配置静态资源访问路径
- 为了让拦截器配置方便!如果拦的/**,那静态资源也会被拦
- 给静态资源加前缀:/res/xxx.jpg,然后再排除以/res开始的目录就可以了
spring:mvc:static-path-pattern: /res/**resources:static-locations: [classpath:/haha/]
4. 访问webjar, 静态资源以jar包形式引入
- 被映射处理成两种请求路径:/webjars/** 和/static-path-pattern属性值/webjars/**
- 例如访问地址:http://localhost:8080/webjars/jquery/3.5.1/jquery.js
<script type="text/javascript" src="${pageContext.request.contextPath }/webjars/jquery/3.5.1/jquery.js">
</script>
<dependency><groupId>org.webjars</groupId><artifactId>jquery</artifactId><version>3.5.1</version>
</dependency>
5. 静态资源默认都有缓存规则的设置
- 所有缓存的设置,直接通过配置⽂件: spring.web
- cachePeriod: 缓存周期; 多久不⽤找服务器要新的。 默认没有,以s为单位
- cacheControl: HTTP缓存控制
- useLastModified:是否使⽤最后⼀次修改。配合HTTP Cache规则
静态资源配置原理
- SpringMVC功能的自动配置类WebMvcAutoConfiguration
- SpringMVC的配置主要集中在这
- 创建xxxConfig类并实现WebMvcConfigurer,就会使WebMvcAutoConfiguration配置类失效,因为在该类中有@ConditionalOnMissingBean(WebMvcConfigurationSupport.class),这个注解会触发
- 主要看WebMvcAutoConfigurationAdapter这一部分


- WebMvcAutoConfigurationAdapter
- 当前2.3.4版本中WebMvcProperties配置文件前缀为spring.mvc、ResourceProperties前缀为spring.resources
- 新版本2.4.2中WebMvcProperties前缀依旧为spring.mvc,ResourcesProperties前缀改为spring.web
WebMvcAutoConfigurationAdapter中只有一个有参构造器
- 参数的值默认都从容器中寻找组件确定
- ResourceProperties resourceProperties:获取和spring.resources绑定的所有的值的对象
- WebMvcProperties mvcProperties :获取和spring.mvc绑定的所有的值的对象
- ListableBeanFactory beanFactory :Spring的beanFactory
- HttpMessageConverters :找到所有的HttpMessageConverters
- ResourceHandlerRegistrationCustomizer :找到资源处理器的自定义器
- DispatcherServletPath
- servletRegistrations :给应用注册Servlet、Filter....

