当前位置:网站首页>四、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场景的静态资源配置原理到这里就分析结束了,下篇再见吧!!!
边栏推荐
- MySQL
- 【Pytorch学习笔记】11.取Dataset的子集、给Dataset打乱顺序的方法(使用Subset、random_split)
- BroadCast Receiver(广播)详解
- 【Promise高级用法】实现并行和串行API
- 通过Flink-Sql将Kafka数据写入HDFS
- 【Kaggle项目实战记录】一个图片分类项目的步骤和思路分享——以树叶分类为例(用Pytorch)
- BFC详解(Block Formmating Context)
- 【论文精读】R-CNN 之预测框回归(Bounding box regression)问题详述
- 【论文阅读-表情捕捉】ExpNet: Landmark-Free, Deep, 3D Facial Expressions
- CVPR最佳论文得主清华黄高团队提出首篇动态网络综述
猜你喜欢

盘点关于发顶会顶刊论文,你需要知道写作上的这些事情!

大型Web网站高并发架构方案

It turns out that the MAE proposed by He Yuming is still a kind of data enhancement

【论文精读】R-CNN 之预测框回归(Bounding box regression)问题详述
![[Database and SQL study notes] 9. (T-SQL language) Define variables, advanced queries, process control (conditions, loops, etc.)](/img/7e/566bfa17c5b138d1f909185721c735.png)
[Database and SQL study notes] 9. (T-SQL language) Define variables, advanced queries, process control (conditions, loops, etc.)

【数据库和SQL学习笔记】8.SQL中的视图(view)

You should write like this

OSPF网络类型

Tensorflow steps on the pit notes and records various errors and solutions

IDEA 配置连接数据库报错 Server returns invalid timezone. Need to set ‘serverTimezone‘ property.
随机推荐
数控直流电源
【论文精读】Rich Feature Hierarchies for Accurate Object Detection and Semantic Segmentation(R-CNN)
TinyFlashDB:一种超轻量的可纠错的通用单片机flash存储方案
Thread handler handle IntentServvice handlerThread
神经网络也能像人类利用外围视觉一样观察图像
[Database and SQL study notes] 9. (T-SQL language) Define variables, advanced queries, process control (conditions, loops, etc.)
Flink和Spark中文乱码问题
沁恒MCU从EVT中提取文件建立MounRiver独立工程
单变量线性回归
CVPR best paper winner Huang Gao's team from Tsinghua University presented the first dynamic network review
【论文阅读-表情捕捉】ExpNet: Landmark-Free, Deep, 3D Facial Expressions
Thread handler句柄 IntentServvice handlerThread
全尺度表示的上下文非局部对齐
flink项目开发-flink的scala shell命令行交互模式开发
如何停止flink job
MySQL
【数据库和SQL学习笔记】10.(T-SQL语言)函数、存储过程、触发器
【数据库和SQL学习笔记】8.SQL中的视图(view)
Spark ML学习相关资料整理
【ts】typescript高阶:条件类型与infer