【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 方法(核心处理请求的方法)

相关推荐
零千叶16 分钟前
【面试】AI大模型应用原理面试题
java·设计模式·面试
坐吃山猪5 小时前
SpringBoot01-配置文件
java·开发语言
我叫汪枫5 小时前
《Java餐厅的待客之道:BIO, NIO, AIO三种服务模式的进化》
java·开发语言·nio
yaoxtao5 小时前
java.nio.file.InvalidPathException异常
java·linux·ubuntu
Swift社区7 小时前
从 JDK 1.8 切换到 JDK 21 时遇到 NoProviderFoundException 该如何解决?
java·开发语言
DKPT8 小时前
JVM中如何调优新生代和老生代?
java·jvm·笔记·学习·spring
phltxy8 小时前
JVM——Java虚拟机学习
java·jvm·学习
seabirdssss9 小时前
使用Spring Boot DevTools快速重启功能
java·spring boot·后端
喂完待续9 小时前
【序列晋升】29 Spring Cloud Task 微服务架构下的轻量级任务调度框架
java·spring·spring cloud·云原生·架构·big data·序列晋升