SpringBoot源码系列(3):静态资源配置

布鸽不鸽 Lv4

前言

WebMvcAutoConfiguration中有一些常用的与静态资源相关的配置项,本文回顾一下其中原理。本文中SpringBoot版本号为2.7.5。

原文地址:https://xuedongyun.cn/post/3386/

静态资源配置原理

WebMvcAutoConfiguration

SpringBoot启动会自动加载WebMvcAutoConfiguration类。(具体原因可以查看我之前的博客:SpringBootApplication注解背后的原理),我们首先看看这个自动配置类生效的条件:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 代码有删减
@AutoConfiguration(after = { DispatcherServletAutoConfiguration.class,
TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class })
// 典型的Web Servlet应用才生效
@ConditionalOnWebApplication(type = Type.SERVLET)
// 导了SpringMVC有这些类,生效
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
// 如果容器中有WebMvcConfigurationSupport类,会全面接管SpringMVC
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
public class WebMvcAutoConfiguration {
}

WebMvcAutoConfigurationAdapter

WebMvcAutoConfiguration类中,还有一个静态类WebMvcAutoConfigurationAdapter。它还绑定了两个属性类WebMvcPropertiesWebProperties,我们可以在配置文件中更改相应配置项的属性,实现对某些功能的自定义

1
2
3
4
5
@Configuration(proxyBeanMethods = false)
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class, WebProperties.class })
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware {
1
2
3
4
5
@ConfigurationProperties(prefix = "spring.mvc")
public class WebMvcProperties {}

@ConfigurationProperties("spring.web")
public class WebProperties {}

WebMvcAutoConfigurationAdapter只有一个构造函数,所有值从容器中获取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public WebMvcAutoConfigurationAdapter(
// 两个属性类
WebProperties webProperties,
WebMvcProperties mvcProperties,
// Spring的IOC容器
ListableBeanFactory beanFactory,
// 所有的messageConverter,此处不涉及
ObjectProvider<HttpMessageConverters> messageConvertersProvider,
// 所有的资源自定义器,重点
ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,
// DispathcerServlet能处理的所有路径,此处不涉及
ObjectProvider<DispatcherServletPath> dispatcherServletPath,
// 应用注册的原生Servlet,Filter...此处不涉及
ObjectProvider<ServletRegistrationBean<?>> servletRegistrations
) {
this.resourceProperties = webProperties.getResources();
this.mvcProperties = mvcProperties;
}

WebMvcAutoConfigurationAdapter类中,有一些与资源相关的核心方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
/*
可以禁用资源的路径映射,所有静态资源都无法访问
spring.web.resources.add-mappings = false
*/
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
/*
所有/webjars/**的静态资源,都会去classpath:/META-INF/resources/webjars/找
*/
addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
/*
staticPathPattern 默认值"/**"
staticLocations 默认值 { "classpath:/META-INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/" }
所有静态资源请求都会去对应路径找
*/
addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
if (this.servletContext != null) {
ServletContextResource resource =
new ServletContextResource(this.servletContext, SERVLET_LOCATION);
registration.addResourceLocations(resource);
}
});
}
1
2
3
4
5
6
7
8
9
10
// 代码有删减
private void addResourceHandler(ResourceHandlerRegistry registry, String pattern,
Consumer<ResourceHandlerRegistration> customizer) {
...
// 比如:可以通过spring.web.cache.period控制缓存的时间
registration.setCachePeriod(getSeconds(this.resourceProperties.getCache().getPeriod()));
registration.setCacheControl(this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl());
registration.setUseLastModified(this.resourceProperties.getCache().isUseLastModified());
...
}

前面提到的配置项

1
2
3
4
5
6
7
8
9
spring:
web:
resources:
add-mappings: false # 关闭静态资源的访问
static-locations: [classpath:/haha/, classpath:/page/] # 静态资源存放路径
cache:
period: 3600 # 静态资源缓存时间(秒)
mvc:
static-path-pattern: /resources/** # 改变静态资源访问路径(便于拦截器放行静态资源)
  • 标题: SpringBoot源码系列(3):静态资源配置
  • 作者: 布鸽不鸽
  • 创建于 : 2023-05-05 19:23:33
  • 更新于 : 2023-06-26 09:30:30
  • 链接: https://xuedongyun.cn//post/3386/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论
此页目录
SpringBoot源码系列(3):静态资源配置