[0242-08].第08节:SpringBoot中SpringMVC的自动配置

发布于:2025-02-10 ⋅ 阅读:(81) ⋅ 点赞:(0)

SpringBoot学习大纲


一、基于SpringBoot搭建Web工程:

1.1.编码实现Web项目的步骤:

a.创建SpringBoot项目

在这里插入图片描述

b.引入场景启动器:

在这里插入图片描述

c.更改配置文件:

在这里插入图片描述


1.2.SSM中的WEB开发配置与SpringBoot中WEB开发自动配置对比:

a.SSM中的WEB开发:

  • 1.在SSM 整合时,需要手动配置 Tomcat 、配置 SpringMVC、配置如何扫描包、配置字符过滤器、配置视图解析器、文件上传等,如下图所示的配置,非常麻烦。在这里插入图片描述
    在这里插入图片描述

b.SpringBoot中的web开发:

在SpringBoot 中,存在自动配置机制,提高开发效率

  • 1.导入web开发的场景:
    在这里插入图片描述
  • 2.引入场景启动器后,就引入了autoconfigure功能
  • 3.@EnableAutoConfiguration注解使用@Import(AutoConfigurationImportSelector.class)批量导入了Web开发所需要的一系列组件

二、分析SpringBoot对SpringMVC的自动配置

2.1.Web开发相关的自动配置类:

  • 1.SpringBoot启动时会默认加载 xxxAutoConfiguration(这些类就是自动配置类)这些类都在如下这个org包中:
    在这里插入图片描述
  • 2.其中与web开发的场景相关的全类名如下所示,SpringBoot会根据这些全类名批量加载自动配置类组件到容器中
    在这里插入图片描述
  • 3.其中对SpringMVC功能相关的自动配置类是:WebMvcAutoConfiguration,下面我们就单独介绍下SpringBoot对SpringMVC的自动配置都配置了哪些

2.2.SpringBoot对SpringMVC自动配置

a.默认的自动配置

在这里插入图片描述

b.定制化开发:

SpringBoot中对SpringMVC的定制化开发有如下三种方式

  • 1.全自动的默认配置:
    • 含义解释:保持 SpringBootMVC的默认配置,并且自定义更多的 mvc 配置,如:interceptors, formatters, view controllers 等
    • 实现方式:使用@Configuration注解添加一个 WebMvcConfigurer 类型的配置类,并不要标注 @EnableWebMvc
  • 2.手动自动结合:
    • 含义解释:保持 SpringBootMVC的默认配置,但要自定义核心组件实例,比如:RequestMappingHandlerMapping, RequestMappingHandlerAdapter, 或ExceptionHandlerExceptionResolver,
    • 实现方式:@Configuration 标注一个配置类,实现 WebMvcConfigurer 接口,给容器中放一个 WebMvcRegistrations 组件即可
  • 3.全手动方式:
    • 含义解释:全面接管 Spring MVC
    • 实现方式:@Configuration 标注一个配置类,并加上 @EnableWebMvc注解,实现 WebMvcConfigurer 接口

2.3.分析WebMvcAutoConfiguration类的源码:

a.定位SpringMVC的自动配置类位置:

  • 1.SpringBoot中对SpringMVC功能的自动配置类是:WebMvcAutoConfiguration,其所在的位置如下图所示
    在这里插入图片描述

b.分析WebMvcAutoConfiguration类源码:

1、WebMvcAutoConfiguration类的源码:

  • 可以看到这个类上@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)、@ConditionalOnClass()、ConditionalOnWebApplication条件注解
    在这里插入图片描述

2、分析:WebMvcAutoConfiguration类生效条件

  • 1.@AutoConfiguration(after = { DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class })意思是:在DispatcherServletAutoConfiguration、TaskExecutionAutoConfiguration(异步任务)、ValidationAutoConfiguration(数据校验)都配置好了之后,WebMvcAutoConfiguration再进行配置
  • 2.@ConditionalOnWebApplication(type = Type.SERVLET)意思是: 如果是web应用就生效,类型是SERVLET、REACTIVE响应式编程
  • 3.@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })意思是:容器中有Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class这些Bean才生效,这里我们引入了web场景,所以可以判断出自动配置类是WebMvcAutoConfiguration是生效的
  • 4.@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)意思是:容器中没有WebMvcConfigurationSupport这个Bean才生效
  • 5.@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10):意思是:定义的是优先级

3、其他说明:(可参照定制化开发分析配置后的效果)

  • 1.如果创建xxxConfig类并实现WebMvcConfiger,就会使WebMvcAutoConfiguration配置类失效,因为在该类中有@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)这个注解会触发
  • 2.@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)这个注解会触发的原因是我们在自定义的xxConfig类中实现了WebMvcConfiger,点进WebMvcConfiger这个接口就可以知道它继承了WebMvcConfigurationSupport,所以springboot自动帮我们配置好的webMvcAutoConfiguration就会失效,注意只是我们在xxxConfig类中重写的default失效

c.分析当webMvcAutoConfiguration生效时会自动配置什么:

c1.配置1:配置了SpringMVC兼容Rest风格的请求
  • HiddenHttpMethodFilter;页面表单提交Rest请求(GET、POST、PUT、DELETE)
    在这里插入图片描述
c2.配置2:配置了表单内容的过滤器
  • 1.可以配合HiddenHttpMethodFilter过滤器使用
  • 2.表单内容Filter,GET(数据放URL后面)、POST(数据放请求体)请求可以携带数据,PUT、DELETE 的请求体数据会被忽略,使用OrderedFormContentFilter可以实现PUT、DELETE类型的请求体不被忽略
    在这里插入图片描述

c3.配置3:配置了静态内部类WebMvcAutoConfigurationAdapter
  • 1.静态内部类WebMvcAutoConfigurationAdapter作用:
    • 1.静态内部类WebMvcAutoConfigurationAdapter的作用就是给容器中放了WebMvcConfigurer组件;给SpringMVC添加各种定制功能
  • 2.静态内部类WebMvcAutoConfigurationAdapter的源码如下图所示,下面我们就对这个源码进行更深层次的分析
    在这里插入图片描述

1、介绍静态内部类WebMvcAutoConfigurationAdapter类所实现的WebMvcConfigurer接口:

====================== SpringBoot2中WebMvcAutoConfigurationAdapter类的源码- - - 开始========================

  • 如下可以看到静态内部类WebMvcAutoConfigurationAdapter仅实现了WebMvcConfigurer接口
    在这里插入图片描述

====================== SpringBoot2中WebMvcAutoConfigurationAdapter类的源码- - - 结束========================


====================== SpringBoot3中WebMvcAutoConfigurationAdapter类的源码- - - 开始========================

  • 1.如下可以看到静态内部类WebMvcAutoConfigurationAdapter实现了WebMvcConfigurer接口和ServletContextAware接口
    在这里插入图片描述
    ====================== SpringBoot3中WebMvcAutoConfigurationAdapter类的源码- - - 结束========================

  • 2.ctrl + F12可以看到WebMvcConfigurer接口中的所有方法,就是这些抽象方法提供了配置SpringMVC底层的所有组件的入口
    在这里插入图片描述

  • 3.下面我对接口中的抽象方法的功能进行了一一说明:
    在这里插入图片描述

2、解析 静态内部类WebMvcAutoConfigurationAdapter上标注的注解 ---- 注解1: @Configuration

========== ==SpringBoot2中静态内部类WebMvcAutoConfigurationAdapter上标注的注解 ---- 开始 =================

  • 在WebMvcAutoConfigurationAdapter类上有注解@Configuration,所以说这个类是属于一个配置类
    在这里插入图片描述

3、解析 静态内部类WebMvcAutoConfigurationAdapter上标注的注解 ---- 注解2: @EnableConfigurationProperties

  • 1.注解@EnableConfigurationProperties 根据@EnableConfigurationProperties({WebMvcProperties.class,ResourceProperties.class})可以看到有对应的xxxxproperties配置属性类,那这就说明了配置文件的属性配置是和实体类xxx绑定在一起的
    在这里插入图片描述
  • 2.由下图可知:配置文件中WebMvcProperties==spring.mvcResourceProperties==spring.resources进行了绑定
    在这里插入图片描述
  • 3.对WebMvcProperties类进行源码分析:与配置文件中的spring.mvc绑定在一起
    在这里插入图片描述
  • 4.对ResourceProperties类进行源码分析:与spring.resources绑定在一起
    在这里插入图片描述

========== ==SpringBoot2中静态内部类WebMvcAutoConfigurationAdapter上标注的注解 ---- 结束 =================


========== ==SpringBoot3中静态内部类WebMvcAutoConfigurationAdapter上标注的注解 — 开始 =================

  • 1.@EnableConfigurationProperties注解: 根据@EnableConfigurationProperties({ WebMvcProperties.class, WebProperties.class })可见有xxxxproperties,这说明配置文件的属性配置是和配置属性类xxx是绑定在一起的
    在这里插入图片描述
  • 2.根据如下源码可知:WebMvcProperties对配置文件中的spring.mvc 进行了绑定
    在这里插入图片描述
  • 3.根据如下源码可知:WebProperties对配置文件中的spring.web 进行了绑定
    在这里插入图片描述

========== ==SpringBoot3中静态内部类WebMvcAutoConfigurationAdapter上标注的注解 — 结束 ========================


4、扩展知识: 当某个配置类只有一个有参构造器的时候,有参构造器所有参数的值都会从容器中确定

  • 这里的WebMvcAutoConfigurationAdapter配置类就是只有一个有参构造器!!!,所以所有参数的值都会从容器中确定
    在这里插入图片描述
    • ResourceProperties resourceProperties;获取和spring.resources绑定的所有的值的对象
    • WebMvcPropertiesmvcProperties :获取和spring.mvc绑定的所有的值的对象
    • ListableBeanFactorybeanFactory :Spring的beanFactory(容器工厂)
    • HttpMessageConverters:找到所有的HttpMessageConverters
    • ResourceHandlerRegistrationCustomizer: 找到资源处理器的自定义器(重点)
    • ServletRegistrationBean:给应用注册Servlet,Filter…

c4.配置4:配置了message Converters

在这里插入图片描述


c5.配置5:配置了视图解析器:

在这里插入图片描述


c6.配置6:配置了资源处理器:
  • 1.在自动配置的这个资源处理器方法中设置了所有资源处理的默认规则

1、下面是SpringBoot配置的资源处理器的源码

  • 1.为了明确springBoot是怎么对资源进行配置的,我们就对其资源处理器源码进行解析:
    在这里插入图片描述

2、分析resourceProperties的值是从哪里来的:

  • 1.在资源处理器源码中可以看到先判断this.resourceProperties.isAddMappings()是否为真
    在这里插入图片描述
  • 2.this.resourceProperties的值是从哪里来的呢?? 根据源码可知,是从这个类的构造函数中进行赋值,然后获取到的在这里插入图片描述
  • 3.在构造器这里的resourceProperties的值都是从容器中拿到的
    在这里插入图片描述

3、查看resourceProperties中的第一个属性是:addMappings

  • 1.点击isAddMappings(),查看isAddMappings()源码
    在这里插入图片描述
  • 2.在isAddMappings()方法中返回了isAddMappings的属性值
    在这里插入图片描述
  • 3.如下代码可以看到isAddMappings属性的默认值是true:
    在这里插入图片描述
  • 4.ResourcesProperties这个属性配置类是和spring.resources绑定在一起的,我在配置文件中设置isAddMappings值为false,这表示资源禁用
    在这里插入图片描述
  • 5.我在配置文件配置后,所有的静态资源都被禁用,执行在if判断中的内容后就return了,那么所有的静态资源将不会被访问到:
    在这里插入图片描述

4、查看resourceProperties中的第二个属性是:Cache

  • 1.Cache 是和配置缓存策略相关的
    在这里插入图片描述
  • 2.配置了缓存默认的时间以秒为单位:
    在这里插入图片描述
  • 3.在SpringBoot的配置文件中进行如下配置
    在这里插入图片描述

5、再继续分析下面的代码:就是判断webjars请求相关的了:

  • 1.当请求是webjars/**时,就去资源目录META-INF/下去查找资源,且同时设置了资源缓存的时间:
    在这里插入图片描述
  • 2.请求测试设置的缓存时间是否生效:
    在这里插入图片描述
    在这里插入图片描述

6、再继续往下分析:this.mvcProperties.getStaticPathPattern

  • 1.再往下就配置了静态资源路径的匹配规则
    在这里插入图片描述
c7.配置7:配置了欢迎页的处理规则:
  • 1.HandlerMapping:就是处理器映射。在其中保存了每一个Handler能处理哪些请求
    	@Bean
    		public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
    				FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
    			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");
    		}
    	}
    
    
  • 2.如下代码截图可以看到要用欢迎页功能,请求路径必须是/**,一旦加了访问前缀,访问欢迎页就会失效了
    在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到