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

相关推荐
HBryce242 分钟前
缓存-基础概念
java·缓存
一只爱打拳的程序猿17 分钟前
【Spring】更加简单的将对象存入Spring中并使用
java·后端·spring
杨荧18 分钟前
【JAVA毕业设计】基于Vue和SpringBoot的服装商城系统学科竞赛管理系统
java·开发语言·vue.js·spring boot·spring cloud·java-ee·kafka
minDuck20 分钟前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js
为将者,自当识天晓地。39 分钟前
c++多线程
java·开发语言
daqinzl1 小时前
java获取机器ip、mac
java·mac·ip
激流丶1 小时前
【Kafka 实战】如何解决Kafka Topic数量过多带来的性能问题?
java·大数据·kafka·topic
Themberfue1 小时前
Java多线程详解⑤(全程干货!!!)线程安全问题 || 锁 || synchronized
java·开发语言·线程·多线程·synchronized·
让学习成为一种生活方式1 小时前
R包下载太慢安装中止的解决策略-R语言003
java·数据库·r语言
晨曦_子画1 小时前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin