15.web场景-【源码分析】-静态资源原理

经过我们分析springboot的自动装配原理之后,我们知道了,再springboot 一启动,就会注册我们导入依赖的场景中的所有组件。

我们要分析静态资源的配置原理,那么我们需要去看关于资源配置的自动配置类,我们直接找到springMVC的自动配置类
位于org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration

springmvc的自动配置类就集中在这个类,但是整个完整的springMVC功能需要和其他的web场景下的自动配置类一起实现。这个配置类是核心配置类

我们查看这个配置为什么会自动生效

很显然,是满足这三个条件的,所以才会执行下面的这些代码

我们接下来看当这个类生效了之后,执行的代码

很显然,是满足这三个条件的,所以才会执行下面的这些代码

我们接下来看当这个类生效了之后,执行的代码

它里面注册了很多组件,还有几个内部类

我们看这个内部类

看到@Configuration(proxyBeanMethods = false)注解我们知道了,当前的内部类是一个配置类,并在再容器中注册了这个配置类的组件,并且是轻量级的配置。
根据@EnableConfigurationProperties这个注解我们知道了,它进行了配置绑定,我们跟入查看这些配置的绑定参数
第一个参数WebMvcProperties.class的绑定前缀为spring.mvc

第二个参数org.springframework.boot.autoconfigure.web.ResourceProperties.class的绑定前缀为spring.resources

第三个参数WebProperties.class的绑定前缀为spring.web

然后接观察发现,我们的当前这个配置类只有一个有参构造器

根据配置类的注入原理,当前类只有一个有参构造器时,那么这个有参构造的参数会默认从容器中获取。

然后我们来看这个有参构造需要从容器中都获取哪些参数

1.WebProperties webProperties:这个参数就是我们上面的那个内部类使用@EnableConfigurationProperties注解再容器中注册了,所以一定可以获取到。也能够获取到spring.mvc为前缀的配置信息
2.WebMvcProperties mvcProperties:这个参数同样使用@EnableConfigurationProperties注解再容器中注册了,它能够获取spring.web为前缀的配置信息
3.ListableBeanFactory beanFactory:这个相当于找我们的spring容器,就是我们的bean工厂

4.ObjectProvider<HttpMessageConverters> messageConvertersProvider:找到所有HttpMessageConverters
5.ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider:找到资源处理器的自定义器
6.ObjectProvider<DispatcherServletPath> dispatcherServletPath:找到处理的路径
7.ObjectProvider<ServletRegistrationBean<?>> servletRegistrations:给应用注册原生的servlet、Filter、Listoner。。。后面再说
按照老师的讲课版本,这个内部类中应该包含一个addResourceHandlers方法,但是我的这个版本是

2.4.3这个版本的。我的这个方法再另一个叫做EnableWebMvcConfiguration的内部类当中

这个内部类也是一个配置类,并且绑定了配置信息,这个绑定的配置信息的前缀为spring.web
我们来看这个内部类中的addResourceHandlers方法

这个方法就是所有资源处理的默认规则

我们一点一点看
首先是resourceProperties.isAddMappings()

这个resourceProperties就是我们的Resource

这个resource就是我们的WebPropertes类中的一个内部类。

跟进查看

我们发现有一个私有的addMapping
然后我们跟进到isAddMapping这个方法

这个方法就是返回的这个私有的addMapping,默认是true。

也就是说这个判断条件是false

所以它就会不走这个而直接走下面的代码。

这也就意味着我们如果返回是一个false的话,就禁用了默认的静态资源处理方式

我们看到WebProperties这个类中的内类Resource的这个addMapping属性有一个set方法,

那么就意味着我们可以通过配置绑定来设置这个addMapping的值

举例示范禁用默认的静态资源处理方式:
先展示不禁用:

成功访问到静态资源

然后测试禁用默认的静态资源处理方式

application.yaml

访问失败,说明禁用成功

然后我们来回过头来看它默认的静态资源处理方式是什么

它有这两种的默认处理方式
第一种的访问规则注册的是/webjars/**,这个就是我们的jar版本的jquery的那种静态文件的访问规则,可以看到它匹配的路径就是类路径下的我们这个路径classpath:/META-INF/resources/webjars/,

然后我们观察第二种的默认注册方式
默认的访问路径是它this.mvcProperties.getStaticPathPattern(),我们跟入getStaticPathPattern这个方法

然后跟入返回的这个staticPathPattern这个属性

发现就是/**,正如注释解释的这个是访问静态资源的目录。

然后我们接着看它默认是去哪里找的这个资源,也就是这个第三个参数

这里使用了lambda的写法,不用在意,
我们跟入下面这个方法查看得到的是什么

首先进入了getLocation方法

然后再跟入staticLocations这个属性

然后跟入到这个字符串数组

发现返回的就是这个数组数组内容分别是

  1. “classpath:/META-INF/resources/”
  2. “classpath:/resources/”
  3. “classpath:/static/”
  4. “classpath:/public/”
    这就是最终获取静态资源的默认路径,正是这四个包

这样静态资源的默认访问规则的原理就大致说清了。

下面的是欢迎页的源码分析

再核心的web自动配置类(WebMvcAutoConfiguration)中有这样一个方法

注册了欢迎页的组件

我们再了解这个欢迎页的源码原理之前需要回顾一个知识点

HanderMapping是什么?
HanderMapping是处理器映射,保存了每一个Handler能处理的请求

我们来看这个参数

这个参数就是默认欢迎页访问的路径
我们跟入查看
WebMvcProperties这个类的getStaticPathPattern方法

这个方法返回的就是默认路径

这个默认路径就是/**。

然后我们看它寻找欢迎页的路径是哪里,这个是该方法的第三个参数设置的

跟进到这个方法查看,源码如下

循环的这个String类型的数组就是我们前面说的那个默认静态资源的数组路径,就是下面这个路径

循环这个stirng类型的数组依次传入到getIndexHtml(location)这个方法中。
我们接着来看这个方法是做什么的

然后我们看这个重载方法是做什么的

如果这个欢迎页存在的话就会返回回来

然后这个方法经过传入参数返回一个WelcomePageHandlerMapping类型的数据

posted @ 2022-08-05 10:48  随遇而安==  阅读(52)  评论(0编辑  收藏  举报