SpringBoot静态资源配置原理
SpringMVC功能的自动配置类为:WebMvcAutoConfiguration,如下
@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 {
给容器中配了什么,就又要看其中一个静态内部类 WebMvcAutoConfigurationAdapter,如下
// Defined as a nested config to ensure WebMvcConfigurer is not read when not
// on the classpath
@Configuration(proxyBeanMethods = false)
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {
其中配置文件的相关属性进行了绑定,有 WebMvcProperties->spring.mvc、ResourceProperties->spring.resources
1、配置类只有一个有参构造器(扩展)
- 有参构造器所有参数的值都会从容器中确定(所以这里通过有参构造参数,便将容器里的组件值赋值给本类成员属性,供其各种场景的使用)
- ResourceProperties resourceProperties --> 获取和spring.resources绑定的所有值的对象
- WebMvcProperties mvcProperties --> 获取和spring.mvc绑定的所有的值的对象
- ListableBeanFactory beanFactory --> Spring的beanFactory
- HttpMessageConverters --> 找到所有的HttpMessageConverter
- ResourceHandlerRegistrationCustomizer --> 找到资源处理器的自定义器
- DispatcherServletPath --> springmvc用的处理器
- ServletRegistrationBean --> 给应用注册Servlet、Filter...
public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebMvcProperties mvcProperties,
ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider,
ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,
ObjectProvider<DispatcherServletPath> dispatcherServletPath,
ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
this.resourceProperties = resourceProperties;
this.mvcProperties = mvcProperties;
this.beanFactory = beanFactory;
this.messageConvertersProvider = messageConvertersProvider;
this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
this.dispatcherServletPath = dispatcherServletPath;
this.servletRegistrations = servletRegistrations;
}
2、资源处理的默认规则
在WebMvcAutoConfigurationAdpter类中的重写了WebMvcConfigurer中的addResourceHanders方法,通过该方法指定资源处理规则,源码如下:
--> 首先进入方法会进行判断,关键方法isAddMappings(),是否启用默认资源处理(true/false)
--> 进入isAddMapprings方法,其值设定在ResourceProperties配置类中,默认值为true,即是默认启用默认资源处理的,不会进入if
--> 其中缓存时间设置:getCache().getPeriod();也都是绑定到资源处理类ResourceProperties中的,其内部设定了 Cahe 内部类对缓存进行设定
--> 小结:通过上述源码中的isAddMappings()和getCache().getPeriod()设置绑定到ResourceProperties类中的设置可知,我们可以配置文件中自行设定,如:
spring:
resources:
static-locations: [classpath:/test/] //指定静态资源映射前缀
add-mapprings: false //禁用默认的资源处理规则
cache:
period: 12300 //设置静态资源缓存时间
重点看启用的默认资源处理规则到底映射了什么
--> addResourceHandler("要处理的映射规则").addResourceLocations("映射到什么路径")
3、欢迎页的处理规则
这里欢迎页处理规则受到了静态资源访问前缀:staticpathPattern的影响,看下面源码:
-->xxxHandlerMapping: 处理映射器,保存了每一个Handler能处理哪些请求
--> 由上述源码可知WelComePageHandlerMapping的构造函数传了欢迎页的关键参数: getWelcomePage(),getStaticPathPattern()...,即看其构造函数源码如何利用,源码如下:
--> 如进入setRootViewName()方法可知,可以controller进行处理
--> 小结:欢迎页规则是写死的,即静态资源访问前缀("/**")被修改了就会失效