SpringBoot3-Web开发-静态资源——WebMvcAutoConfiguration原理&资源映射&资源缓存&欢迎页&Favicon&自定义

上一篇:SpringBoot3-日志——日志原理&日志格式&日志级别&日志分组&文件输出&文件归档&滚动切割

静态资源

1、WebMvcAutoConfiguration原理

1.生效条件

在这个原理里找到自动配置类,ctrl+N搜索WebMvcAutoConfiguration
在这里插入图片描述

如果接入了其它平台的设置,可以在setting中搜索keymap,选择windows后点击apply恢复默认设置。

WebMvcAutoConfiguration前写了一堆注解:

@AutoConfiguration(
    after = {DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class}
)     //
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
@ImportRuntimeHints({WebResourcesRuntimeHints.class})
public class WebMvcAutoConfiguration {
  1. 第一条:@AutoConfiguration

    • 其中的after是指在{}中的自动配置配置好后,自己再配。
    @AutoConfiguration(
        after = {DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class}
    )
    
  2. 第二条:@ConditionalOnWebApplication,如果是web应用就生效。

    • Conditional可以当作判断的意思(生效条件)。
    • type = Type.SERVLET表示如果是serverlet类型的web应用才生效。(如果是REACTIVE,则为响应式web)
    • 这的生效就是指后面的public class WebMvcAutoConfiguration {
    @ConditionalOnWebApplication(
        type = Type.SERVLET
    )
    
  3. 第三条:@ConditionalOnClass

    • 当系统中存在{}中的这些类才生效。
    • 导入了springMVC,就有DispatcherServlet.class, WebMvcConfigurer.class,导入了servlet,就有Servlet.class
    @ConditionalOnClass(
    	{Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class}
    )
    
  4. 第四条:@ConditionalOnMissingBean

    • 容器中没有这个been才生效,WebMvcAutoConfiguration才生效。
    • 默认是没有的。
    @ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
    
  5. 第五条:@AutoConfigureOrder(-2147483638)

    • 优先级

2.效果(生效后做了什么)

  1. WebMvcAutoConfiguration查找,发现有两个@Bean,里面有两个Filter
    • HiddenHttpMethodFilter:页面表单提交Rest请求(表单默认只有GET、POST,如果添加了这个Filter,PUT、DELETE也可以提交了)
    • FormContentFilter:表单内容Filter,这是配合上面HiddenHttpMethodFilter的,默认情况下,只有GET(数据放URL后面)、POST(放请求体中)可以携带数据,PUT、DELETE的请求体数据会被忽略。这时加上FormContentFilter就能不会忽略了。
      在这里插入图片描述
  2. 继续往下看,可以看到又有一个内部类,叫WebMvcAutoConfigurationAdapter,它实现了WebMvcConfigurer(这个很重要)。
    • 给容器中放了WebMvcConfigurer组件,这个组件又给添加各种定制功能
    • 比如参数解析器:controller上标的所有参数,都要由参数解析器来解析。
    • 下图中从上往下分别是:
      • 参数解析器
      • 跨域
      • 格式化器
      • 拦截器
      • 添加资源处理器(处理静态资源规则)
      • 返回值处理器
      • 视图控制器(/a直接跳转到 xxx.html 页面)
      • 异步支持
      • 内容协商
      • 默认处理(默认接受:/)
      • 配置异常解析器
      • 消息转化器
      • 路径匹配
      • 视图解析
      • 扩展:异常解析器
      • 扩展:消息转换
        在这里插入图片描述

在这里插入图片描述

2、静态资源规则源码解析

静态资源规则源码,在WebMvcAutoConfiguration.class下:

public void addResourceHandlers(ResourceHandlerRegistry registry) {
            if (!this.resourceProperties.isAddMappings()) {
                logger.debug("Default resource handling disabled");
            } else {
                this.addResourceHandler(registry, this.mvcProperties.getWebjarsPathPattern(), "classpath:/META-INF/resources/webjars/");
                this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (Consumer)((registration) -> {
                    registration.addResourceLocations(this.resourceProperties.getStaticLocations());
                    if (this.servletContext != null) {
                        ServletContextResource resource = new ServletContextResource(this.servletContext, "/");
                        registration.addResourceLocations(new Resource[]{resource});
                    }

                }));
            }
        }

多分析一两个场景的自动配置,就可以熟练SpringBoot的一些用法了。

这个静态资源规则,将addResourceHandler方法调用了两遍,添加了两种静态资源规则。

1.规则一:访问/webjars/**,就去classpath:/META-INF/resources/webjars/下找资源

第一种,有一个MVC静态路径(mvcProperties.getWebjarsPathPattern

this.addResourceHandler(registry, this.mvcProperties.getWebjarsPathPattern(), "classpath:/META-INF/resources/webjars/");

上面这条的意思是,Webjars的静态路径指向"classpath:/META-INF/resources/webjars/",访问Webjars,就会默认去指向的这个位置找资源。
ctrl+鼠标左键 点一下getWebjarsPathPattern,进入后再 ctrl+鼠标左键 点击里面的webjarsPathPattern,最后得到以下内容:

private String webjarsPathPattern = "/webjars/**";

可以得知访问/webjars/**,就去classpath:/META-INF/resources/webjars/下找资源。

2.规则二:访问/**,就去静态资源默认的四个位置找资源

和前一条一样的操作依次点进getStaticPathPatternstaticPathPattern,可以得到以下内容(其实就在规则一的private String webjarsPathPattern = "/webjars/**";上面):

	private String staticPathPattern = "/**";

在这里插入图片描述
与规则一不同的是,这里点击后面resourceProperties后面的getStaticLocations,再点击,可以得到以下内容:

		private static final String[] CLASSPATH_RESOURCE_LOCATIONS =
		 new String[]{
		 "classpath:/META-INF/resources/", "classpath:/resources/", 
		 "classpath:/static/", "classpath:/public/"
		 };


可以得知静态资源默认的四个位置为:
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/"
只要将所有的静态资源放到以上四个文件夹中,项目就可以访问(没有可以自己创建,在resources下创建)。

3.规则三:静态资源默认都有缓存规则的设置

静态资源的访问是通过addResourceHandler来完成的,ctrl+鼠标左键第二个addResourceHandler进入里面,可以看到三个catch,是缓存相关的规则。

registration.setCachePeriod(this.getSeconds(this.resourceProperties.getCache().getPeriod()));
                registration.setCacheControl(this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl());
                registration.setUseLastModified(this.resourceProperties.getCache().isUseLastModified());

如果浏览器访问了一个静态资源 index.js,如果服务器里这个资源没有发生改变,下次访问就可以直接让浏览器用自己缓存的东西,而不用给服务器发请求。
下依次说明这三个catch。

  1. catchPeriod:缓存周期,以s为单位(getSeconds),每过多久就找服务器更新。依次点击getPeriodPeriod发现没有设置默认值,那默认值就是0
  2. cacheControl:HTTP缓存控制
  3. useLastModified:是否使用最后一次修改。比如:
    • 浏览器在第一次访问服务器的一个静态资源后,又第二次访问这个资源,不是直接问服务器下载静态资源,而是先问最后一次的修改时间;
    • 如果这个时间和自己第一次访问的修改时间一致,就不用下载资源了,直接使用自己缓存的资源就可以了;
    • 若是修改时间不一致,就再发一次请求,下载该静态资源。

所有缓存的设置,直接通过配置文件spring.web
点击resourceProperties后,再点左边的Resources,发现在WebProperties下,而它的配置文件的设置在spring.web下。
在这里插入图片描述

在这里插入图片描述

3.欢迎页规则

ctrl+n 搜索进入WebMvcAutoConfiguration.class,找到以下内容:
在这里插入图片描述
在这里面找到WebMvcConfigurer这个组件,在这里面配置了静态资源的规则。
在这里插入图片描述

EnableWebMvcConfiguration源码

再往下看可以看到EnableWebMvcConfiguration组件,由其上面的@Configuration(proxyBeanMethods = false)可以得知,这也是个配置类:
在这里插入图片描述

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties({WebProperties.class})
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
}

SpringBoot给容器中放了WebMvcConfigurationSupport组件,如果我们自己放了WebMvcConfigurationSupport组件,SpringBoot放的就失效了。

点进DelegatingWebMvcConfiguration发现了WebMvcConfigurationSupport,这个在前面分析WebMvcAutoConfiguration源码时出现过,是@ConditionalOnMissingBean(容器中没有这个been才生效)的内容,但那时启动时进行的判断,现在这里已经启动了,所以这二者之间不存在冲突:
在这里插入图片描述

往下看,可以找到WelcomePageHandlerMapping,而不管HandlerMapping前面是什么,这些HandlerMapping都有一个作用:根据请求路径/*找那个handler处理请求。
WelcomePageHandlerMapping:访问静态资源路径下的所有请求,都在前面找到的四个静态资源路径下找,欢迎页也是一样(循着类一路点下去可以找到):
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/"
我们往下翻,可以发现一个方法

在这里插入图片描述

其中的for(String location : this.resourceProperties.getStaticLocations()),意思就是遍历这些地方找location,点进getIndexHtml发现:

在这里插入图片描述
再往下看,里面有一个index.html,这个就是欢迎页。

也就是说在四个静态资源路径下放一个index.html,浏览器访问服务器就会默认访问这个index.html
在这里插入图片描述

Favicon

  • 网站每次访问服务器时,都会在静态资源目录下寻找Favicon,找项目的静态资源库里有没有一个Favicon.ico,这个就是网页图标。
  • 这和SpringBoot没多大关系,和浏览器有关系。

4、自定义静态资源规则

自定义静态资源路径、自定义缓存规则

配置方式

怎么知道在配置文件中配什么,就能自定义一些静态资源的规则?

1.自定义webjars路径前缀

之前在分析WebMvcAutoConfiguration的时候,往下翻,可以看到:
在这里插入图片描述
这个WebMvcConfigurer之前提到过,非常重要,这个接口定义了SpringMVC底层所有的组件入口,如果要使用静态资源,在WebMvcConfigurer中就有资源处理器的相关配置。

  • 以分析静态资源为例,以后分析所有配置都是这样。以这个WebMvcAutoConfigurationAdapter为例,从它上面的@EnableConfigurationProperties({WebMvcProperties.class, WebProperties.class})可以得知,它绑定了两个配置文件,分别为WebMvcProperties.class, WebProperties.class
  • ctrl+鼠标左键点进WebMvcProperties.class,得到以下内容,可以知道它绑定的是spring.mvc的配置:
    在这里插入图片描述
  • ctrl+鼠标左键点进WebProperties.class,得到以下内容,可以知道它绑定的是spring.web的配置:
    在这里插入图片描述
  • 所以,搞清楚这两个文件能配置的一些静态资源的规则就行了。
  • 点进spring.mvc可以看到,有许多策略:在这里插入图片描述
    这些都不管,回到WebMvcAutoConfiguration往下找静态资源这一部分功能,addResourceHandlers
    在这里插入图片描述
    点进getWebjarsPathPattern(获得路径),再点进webjarsPathPattern,发现它就在绑定了spring.mvcWebMvcProperties下:在这里插入图片描述
    按照这个路径,我们可以知道,在配置文件application.properties中,输入spring.mvc.webjars-path-pattern=/a/**来修改配置。其中的/a为自定义的静态资源文件夹,在配置文件中修改后,在浏览器内访问/a/**(**为webjars的内容)就能得到webjars的内容。
  • 自定义webjars路径前缀:spring.mvc.webjars-path-pattern=/webjars/**
2.自定义静态资源访问路径前缀
  • 同理,访问getStaticPathPattern可以得到静态资源访问路径前缀:spring.mvc.static-path-pattern=/**在这里插入图片描述
3.自定义静态资源文件夹位置
  • 这次点进getStaticLocations在这里插入图片描述
    再点进staticLocations,往上翻,发现是在spring.web下:
    在这里插入图片描述
    所以,在application.properties中,输入spring.web.resources.static-locations=
    这的默认路径为:classpath:/META-INF/resources/, classpath:/resources/, classpath:/static/, classpath:/public/,这些是浏览器可访问的静态资源的存放目录,想要自定义修改,就在spring.web.resources.static-locations=后面输入想自定义的路径即可,修改后浏览器就可以在自定义的目录下找静态资源了。

spring.web.resources里还定义了很多可自定义的配置,可以在application.properties自定义。

上一篇:SpringBoot3-日志——日志原理&日志格式&日志级别&日志分组&文件输出&文件归档&滚动切割

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值