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

我们要分析静态资源的配置原理,那么我们需要去看关于资源配置的自动配置类,我们直接找到springMVC的自动配置类

位于org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_内部类


springmvc的自动配置类就集中在这个类,但是整个完整的springMVC功能需要和其他的web场景下的自动配置类一起实现。这个配置类是核心配置类我们查看这个配置为什么会自动生效

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_spring_02


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

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

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

我们看这个内部类

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_静态资源_03

看到@Configuration(proxyBeanMethods = false)注解我们知道了,当前的内部类是一个配置类,并在再容器中注册了这个配置类的组件,并且是轻量级的配置。

根据@EnableConfigurationProperties这个注解我们知道了,它进行了配置绑定,我们跟入查看这些配置的绑定参数

第一个参数WebMvcProperties.class的绑定前缀为spring.mvc

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_spring_04


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

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_静态资源_05


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

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_spring_06


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

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_静态资源_07


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

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

  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方法,但是我的这个版本是

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_静态资源_08


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

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_静态资源_09


这个内部类也是一个配置类,并且绑定了配置信息,这个绑定的配置信息的前缀为spring.web

我们来看这个内部类中的addResourceHandlers方法

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_静态资源_10


这个方法就是所有资源处理的默认规则我们一点一点看

首先是resourceProperties.isAddMappings()

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_spring_11


这个resourceProperties就是我们的Resource

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_内部类_12


这个resource就是我们的WebPropertes类中的一个内部类。跟进查看

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_静态资源_13


我们发现有一个私有的addMapping

然后我们跟进到isAddMapping这个方法

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_内部类_14


这个方法就是返回的这个私有的addMapping,默认是true。也就是说这个判断条件是false

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_spring_15


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

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

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

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_内部类_16


那么就意味着我们可以通过配置绑定来设置这个addMapping的值举例示范禁用默认的静态资源处理方式:

先展示不禁用:

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_spring_17


spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_内部类_18


成功访问到静态资源

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

application.yaml

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_spring_19


访问失败,说明禁用成功

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_静态资源_20

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

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_内部类_21


它有这两种的默认处理方式

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

默认的访问路径是它this.mvcProperties.getStaticPathPattern(),我们跟入getStaticPathPattern这个方法

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_spring_22


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

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_spring_23


发现就是/**,正如注释解释的这个是访问静态资源的目录。然后我们接着看它默认是去哪里找的这个资源,也就是这个第三个参数

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_内部类_24


这里使用了lambda的写法,不用在意,

我们跟入下面这个方法查看得到的是什么

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_静态资源_25


首先进入了getLocation方法

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_内部类_26


然后再跟入staticLocations这个属性

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_静态资源_27


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

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_静态资源_28


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

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

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

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

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

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_spring_29


注册了欢迎页的组件

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

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

我们来看这个参数

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_静态资源_30


这个参数就是默认欢迎页访问的路径

我们跟入查看

WebMvcProperties这个类的getStaticPathPattern方法

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_静态资源_31


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

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_spring_32


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

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_静态资源_33


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

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_spring_34


spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_内部类_35

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

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_静态资源_36


循环这个stirng类型的数组依次传入到getIndexHtml(location)这个方法中。

我们接着来看这个方法是做什么的

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_内部类_37


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

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_内部类_38


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

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_spring_39

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

spring boot 和bootstrap整合后静态资源配置 springboot静态资源原理_静态资源_40

这个类中就设置了视图名字。。。。。大概这个意思把,这个欢迎页的源码分析可能有些问题