当前位置:网站首页>四、Web场景之静态资源配置原理
四、Web场景之静态资源配置原理
2022-08-05 05:16:00 【呆比特】
四、Web场景之静态资源配置原理
前边我们讲过,研究SpringBoot原理的第一步,首先启动SpringBoot,它会帮我们默认加载许多的自动配置类,就是那一堆 xxxAutoConfiguration ,我们想要研究Web场景下的静态资源配置,所以我们直接来到 spring-boot-autoconfigure-2.4.0.jar 包下的web场景 ,里边有一个 WebMvcAutoConfiguration ,大部分SpringMVC功能的自动配置都在这里边,接下来我们就从这里开始研究。
现在,我们拿到了这个类,先不要急着去看内容,首要应该看这个类是否生效,从类上边的这些注解来看,它是生效的
既然是生效的,我们就来看下它给容器中配了什么,因为配了什么,就会有什么样的功能。
来到 WebMvcAutoConfiguration 类往下看,翻着翻着看到下边又有一个类
我们要注意一下这个类,因为这个类上边有一个注解 @EnableConfigurationProperties ,表示配置文件和相关属性进行了绑定,点进去看看是怎么绑定的
得出的结果是:WebMvcProperties == spring.mvc、ResourceProperties == spring.resources
得出这个结论后,我们继续看,咦,发现 WebMvcAutoConfigurationAdapter 这个配置类只有一个有参构造器,我们知道,如果一个配置类只有一个有参构造器,那么这个有参构造器所有参数的值都会从容器中确定 ,所以我们来看下这个构造器的参数,看看它到底获取了哪些东西:
1. 配置类只有一个有参构造器:容器获取参数值
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;
}
我们来分析它的参数及代表的含义:
ResourceProperties :获取和spring.resources绑定的所有的值的对象
WebMvcProperties :获取和spring.mvc绑定的所有的值的对象
ListableBeanFactory :Spring的bean工厂
ObjectProvider :找到所有的HttpMessageConverters
ObjectProvider :找到资源处理器的自定义器
ObjectProvider:DispatcherServlet路径
ObjectProvider<ServletRegistrationBean<?>>:给应用注册Servlet、Filter等等
现在,我们的配置类已经拿到了它想要的所有东西,接下来来看他要干嘛,在这里我们先不去关注其他的一些功能,主要关注资源处理有关的东西,比如我们一直向下找,有一个如下的类
2. 资源处理的默认规则
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//首先拿到了spring.resources下的一个属性addMappings,配置为false就直接返回,下边的代码无效了
//这里表示,我们可以通过配置文件,禁用掉静态资源的路径映射,静态资源就不能访问了
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的访问规则,也有缓存功能,可以缓存你配置的一段时间
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
//静态资源路径的配置规则,staticPathPattern 在spring.mvc里边
//如果我们配置了,就获取我们配置的值,否则为“/**”,也就是在我们指定的位置去找
//指定默认位置在哪里呢,下边的代码有个resourceProperties.getStaticLocations()
//默认路径的代码贴到这段下边,而且静态资源都有缓存策略
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
.addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
}
默认静态资源路径源码
//下边为四个默认路径
public class ResourceProperties {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{
"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"};
private String[] staticLocations;
private boolean addMappings;
private final ResourceProperties.Chain chain;
private final ResourceProperties.Cache cache;
//下边代码省略没有贴
上边就是资源处理的默认规则的主要代码啦,debug的结果已经在注释写明白了,感兴趣的可以自己debug一下哦!
3. 欢迎页的处理规则
我们继续往下找,发现一个 EnableWebMvcConfiguration 类,里边有一个 welcomePageHandlerMapping() 方法,是用来处理欢迎页的处理规则的,在看这段代码之前,我们先来普及一个知识点, 在SpringMVC中,有一个 HandlerMapping,叫做处理器映射,作用是保存了每一个Handler能处理哪些请求 ,知道了这个以后,我们就可以理解 welcomePageHandlerMapping() 这个方法了,表示谁能处理这个欢迎页的映射规则。我们来看代码
@Bean
//参数已经从容器中获取好了,我们不用考虑
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
//new 并初始化一个WelcomePageHandlerMapping,里边代码在下边展示
WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
this.mvcProperties.getStaticPathPattern());
welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());
return welcomePageHandlerMapping;
}
WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders,
ApplicationContext applicationContext, Optional<Resource> welcomePage, String staticPathPattern) {
if (welcomePage.isPresent() && "/**".equals(staticPathPattern)) {
//这里直接写死了,要用欢迎页功能,必须是/**
logger.info("Adding welcome page: " + welcomePage.get());
setRootViewName("forward:index.html");
}
else if (welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
// 否则调用Controller 看谁能处理/index
logger.info("Adding welcome page template: index");
setRootViewName("index");
}
}
上边就是欢迎页的处理规则主要代码啦,debug的结果已经在注释写明白了,感兴趣的可以自己debug一下哦!
Web场景的静态资源配置原理到这里就分析结束了,下篇再见吧!!!
边栏推荐
猜你喜欢
单变量线性回归
MSRA proposes extreme masking model ExtreMA for learning instances and distributed visual representations
【论文阅读-表情捕捉】High-quality Real Time Facial Capture Based on Single Camera
[Pytorch study notes] 10. How to quickly create your own Dataset dataset object (inherit the Dataset class and override the corresponding method)
【数据库和SQL学习笔记】10.(T-SQL语言)函数、存储过程、触发器
基于STM32F407的一个温度传感器报警系统(用的是DS18B20温度传感器,4针0.96寸OLED显示屏,并且附带日期显示)
网络ID,广播地址,掩码位数计算
5G中切片网络的核心技术FlexE
[Database and SQL study notes] 9. (T-SQL language) Define variables, advanced queries, process control (conditions, loops, etc.)
【数据库和SQL学习笔记】6.SELECT查询4:嵌套查询、对查询结果进行操作
随机推荐
关于使用QML的MediaPlayer实现视频和音频的播放时遇到的一些坑
【Pytorch学习笔记】9.分类器的分类结果如何评估——使用混淆矩阵、F1-score、ROC曲线、PR曲线等(以Softmax二分类为例)
【数据库和SQL学习笔记】4.SELECT查询2:排序(ORDER BY)、聚合函数、分组查询(GROUP BY)
[Go through 11] Random Forest and Feature Engineering
A deep learning code base for Xiaobai, one line of code implements 30+ attention mechanisms.
基于Flink CDC实现实时数据采集(一)-接口设计
Thread handler句柄 IntentServvice handlerThread
Service
MaskDistill-不需要标注数据的语义分割
WCH系列芯片CoreMark跑分
flink yarn-session的两种使用方式
【Promise高级用法】实现并行和串行API
You should write like this
BFC详解(Block Formmating Context)
物联网-广域网技术之NB-IoT
It turns out that the MAE proposed by He Yuming is still a kind of data enhancement
Web Component-处理数据
【论文精读】R-CNN 之预测框回归(Bounding box regression)问题详述
[Practice 1] Diabetes Genetic Risk Detection Challenge [IFLYTEK Open Platform]
AIDL detailed explanation