【Spring MVC】MVC原理:DispatcherServlet的初始化,初始化好等于MVC准备好

文章目录

  • [1. @EnableWebMVC 开启 MVC 功能](#1. @EnableWebMVC 开启 MVC 功能)
  • [2. 初始化自定义的 MVC 组件](#2. 初始化自定义的 MVC 组件)
    • [2.1. 过程](#2.1. 过程)
    • [2.2. 如何分析复杂的 Spring 组件注册](#2.2. 如何分析复杂的 Spring 组件注册)
  • [3. 容器启动后会初始化 DispatcherServlet](#3. 容器启动后会初始化 DispatcherServlet)
  • [4. DispatcherServlet 初始化过程总结](#4. DispatcherServlet 初始化过程总结)

把DispatcherServlet 准备好意味着服务器已经可以处理请求了,那么DispatcherServlet 是如何初始化的。

1. @EnableWebMVC 开启 MVC 功能

在 Spring MVC 中可以通过贴该注解的方式来开启 MVC 功能。Spring Boot 只要引入了 web 的 starter 就已经开启了。

注意:但是在 Spring Boot 中慎重使用该注解,该注解会导致 Spring Boot 自动装配失效,所有 Boot 增强的组件全部失效,会导致功能退化为 MVC。

2. 初始化自定义的 MVC 组件

工作过程概述:

1、初始化WebMvcConfigurationSupport 中定义的各个 bean

2、各个 bean 的初始化触发DelegatingWebMvcConfiguration 各个方法的调用

3、方法的调用触发WebMvcConfigurer 的调用

4、WebMvcConfigurer 就是用户自定义的配置

2.1. 过程

  • 容器启动后会开始 bean 的初始化过程。

mvc 相关的 bean 的初始化其实彼此一点关系都没有,各自初始化各自的,各自安好。但是当初始化到WebMvcConfigurationSupport中定义的Bean 的时候,会触发DelegatingWebMvcConfiguration类各个方法的调用;方法的调用又关联到WebMvcConfigurer,WebMvcConfigurer又关联到我们的组件,最后都会初始化好。

  • 初始化WebMvcConfigurationSupport 中定义的 bean
java 复制代码
public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware {

    ......
    @Bean
	public RequestMappingHandlerMapping requestMappingHandlerMapping()

    ......
    
    @Bean
	public PathMatcher mvcPathMatcher() {}
    ......
    
}
  • bean 的初始化导致DelegatingWebMvcConfiguration各个方法的执行
java 复制代码
@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
	
    private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();

	@Autowired(required = false)
	public void setConfigurers(List<WebMvcConfigurer> configurers) {
		if (!CollectionUtils.isEmpty(configurers)) {
			this.configurers.addWebMvcConfigurers(configurers);
		}
	}
    
    @Override
	protected void configurePathMatch(PathMatchConfigurer configurer) {
		this.configurers.configurePathMatch(configurer);
	}

	@Override
	protected void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
		this.configurers.configureContentNegotiation(configurer);
	}

	.........
}
  • 各个方法的执行导致WebMvcConfigurer 生效
  • 用户通过继承WebMvcConfigurer 自定义 mvc 的组件,自定义组件生效

2.2. 如何分析复杂的 Spring 组件注册

带@Bean继承关系的复杂 Spring 组件如何分析参考:https://www.yuque.com/yuchangyuan/kkc8mp/ot7orhqpmmqictqx

3. 容器启动后会初始化 DispatcherServlet

容器启动后会初始化DispatcherServlet,并把MVC相关的bean都设置到DispatcherServlet的属性中,之后处理请求只需用到属性即可。

java 复制代码
protected void initStrategies(ApplicationContext context) {
    initMultipartResolver(context);
    initLocaleResolver(context);
    initThemeResolver(context);
    initHandlerMappings(context);
    initHandlerAdapters(context);
    initHandlerExceptionResolvers(context);
    initRequestToViewNameTranslator(context);
    initViewResolvers(context);
    initFlashMapManager(context);
}
  • 问题:之前的自动装配阶段不是有很多种 bean 吗,怎么现在才这么几种?

因为各个组件都整合到了这 9 种 bean 之中了。

4. DispatcherServlet 初始化过程总结

1、开启 MVC 功能

Spring Boot 只要引入 starter 即可。

2、通过@Bean 方式给容器注册相关的 mvc 组件

用户自定义一般通过实现 WebMvcConfiguration 实现

3、mvc 组件的初始化(重难点)核心类:WebMvcConfigurationSupport

4、执行DispatcherServlet 的initStrategies 方法设置属性

5、截止DispatcherServlet 准备好,MVC 就准备好了

6、之后的 http 请求直接在DispatcherServlet 处理即可。

1、先 service 方法(该方法会准备一些东西)

2、后 doDispatcher 方法(核心处理请求的方法)

相关推荐
代码什么用5 小时前
Spring基础使用
java·后端·spring
代码什么用5 小时前
Spring对IoC的实现
数据库·spring
Su米苏5 小时前
Spring AI 中MCP 与普通 @Tool的区别
java·人工智能·spring
码云数智-园园5 小时前
unique_ptr 还是 shared_ptr?C++ 智能指针选型与内存泄漏实战分析
java·开发语言
老板一杯拿铁5 小时前
Java 异常体系详解:从字节码原理到最佳实践
java
蜗牛互联网6 小时前
Java 17 HttpClient调用文件转写API的超时与失败回退
java·人工智能·后端
禾小西6 小时前
07丨Redis 哨兵机制:主库故障后,如何恢复服务?
java·开发语言·redis
我不是阵雨6 小时前
JDK 21虚拟线程Pinning陷阱:一文拔钉解困
java·开发语言
小卡车5557 小时前
java反射、自定义注解的应用(自定义分页)
java
BLUcoding7 小时前
接口服务公网超时排查记录:SecureRandom 阻塞问题分析与解决
java·linux·springboot·aes·securerandom