SpringMVC之DispatcherServlet组件

2024-03-05 14:44

本文主要是介绍SpringMVC之DispatcherServlet组件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 一、SpringMVC的核心处理流程
  • 二、DispatcherServlet
    • 1、init()方法
    • 2、doDispatch()方法
    • 3、AbstractAnnotationConfigDispatcherServletInitializer类



一、SpringMVC的核心处理流程

  1. 请求到达 DispatcherServlet

  2. DispatcherServlet 的请求处理
  • DispatcherServlet 接收到请求后,会通过 HandlerMapping 找到处理该请求的 Controller。

  1. 处理器映射(Handler Mapping)
  • HandlerMapping 将请求映射到对应的处理器(Controller)上。

  1. 处理器执行
  • DispatcherServlet 调用处理器(Controller)的适当方法来处理请求。这个方法执行业务逻辑,并返回 Model 对象和逻辑视图名。

  1. 视图解析器解析逻辑视图名
  • DispatcherServlet 使用视图解析器(ViewResolver)将逻辑视图名解析为具体的视图对象。

  1. 视图渲染
  • DispatcherServlet 将 Model 对象传递给视图,视图使用 Model 中的数据生成响应内容(例如 HTML 页面)。

  1. 响应返回客户端
  • DispatcherServlet 将生成的响应内容返回给客户端。


二、DispatcherServlet

SpringMVC提供了 DispatcherServlet ,可以负责请求的分发、处理器的调用、视图的解析和呈现,以及拦截器的调用等任务,是整个 Spring MVC 框架的核心组件之一


1、init()方法

处理了 WebApplicationContext 的创建和初始化,还有设置和配置 Servlet 环境,注册和初始化 Servlet 的内部组件以及其他自定义的初始化操作等


WebApplicationContext 是 Spring 框架中用于管理 Web 应用程序配置信息的上下文接口。它扩展了普通的 Spring 应用上下文 ApplicationContext,并添加了一些特定于 Web 应用的功能和特性。(WebApplicationContext 是 ApplicationContext 接口的一个子接口)


2、doDispatch()方法

DispatcherServlet 中的 doDispatch() 方法是核心的请求分发方法,用于将请求分发给适当的处理器(Handler)进行处理。在请求处理过程中,还会涉及参数绑定、数据验证、视图解析等其他操作。

// 简化版
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {// 获取请求处理器(通过 HandlerMapping 建立请求URL和Handler方法之间的映射关系)// 遍历所有的处理器映射器,尝试从中找到适合当前请求的处理器,并返回执行链(HandlerExecutionChain)HandlerExecutionChain handler = getHandler(request);if (handler == null) {// 如果没有合适的处理器,返回 404 错误response.sendError(HttpServletResponse.SC_NOT_FOUND);return;}// 应用请求预处理器if (!applyPreHandle(request, response, executionChain.getInterceptors())) {return;}// 找多Handler对应的请求处理器HandlerAdapter handlerAdapter = getHandlerAdapter(handler.getHandler());// 执行Handler方法handlerAdapter.handle(request, response, handler.getHandler());// 应用请求后处理器applyPostHandle(request, response, executionChain.getInterceptors(), executionChain.getHandler());// 触发请求完成后的处理triggerAfterCompletion(request, response, null);protected boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response, HandlerInterceptor[] interceptors) throws Exception {if (interceptors != null) {// 遍历所有的请求预处理器(拦截器)for (int i = 0; i < interceptors.length; i++) {HandlerInterceptor interceptor = interceptors[i];// 调用请求预处理器的preHandle()方法if (!interceptor.preHandle(request, response, handler)) {// 如果某个预处理器返回false,表示拦截请求,直接返回falsetriggerAfterCompletion(request, response, null, new Exception("Interceptor[" + interceptor + "] preHandle return false"));return false;}}}// 所有的预处理器都通过,返回truereturn true;}protected void applyPostHandle(HttpServletRequest request, HttpServletResponse response, HandlerInterceptor[] interceptors, Object handler) throws Exception {if (interceptors != null) {// 逆序遍历所有的请求后处理器(拦截器)for (int i = interceptors.length - 1; i >= 0; i--) {HandlerInterceptor interceptor = interceptors[i];// 调用请求后处理器的postHandle()方法interceptor.postHandle(request, response, handler, null);}}}
}

3、AbstractAnnotationConfigDispatcherServletInitializer类

是 WebApplicationInitializer 接口的一个抽象实现,
可以通过继承 AbstractAnnotationConfigDispatcherServletInitializer 类,并重写其中的方法,来实现自定义的初始化配置,不需要传统的 web.xml 文件
Spring Boot 提供了自动配置机制,会自动配置 Spring MVC 环境,包括注册 DispatcherServlet、处理器映射器、处理器适配器、视图解析器等,无需手动配置。

// 简化版
public abstract class AbstractAnnotationConfigDispatcherServletInitializerimplements WebApplicationInitializer {@Overridepublic void onStartup(ServletContext servletContext) throws ServletException {// 创建根上下文AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();Class<?>[] rootConfigClasses = getRootConfigClasses();if (rootConfigClasses != null && rootConfigClasses.length > 0) {rootContext.register(rootConfigClasses);}// 创建 DispatcherServlet 上下文AnnotationConfigWebApplicationContext servletContext = new AnnotationConfigWebApplicationContext();Class<?>[] servletConfigClasses = getServletConfigClasses();if (servletConfigClasses != null && servletConfigClasses.length > 0) {servletContext.register(servletConfigClasses);}// 注册 DispatcherServletDispatcherServlet dispatcherServlet = new DispatcherServlet(servletContext);ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", dispatcherServlet);dispatcher.addMapping(getServletMappings());// 添加额外的配置customizeRegistration(dispatcher);}// 用于配置 Spring 根上下文(即应用程序上下文)的配置类protected abstract Class<?>[] getRootConfigClasses();// 用于配置 DispatcherServlet 的上下文(即 Web 上下文)的配置类protected abstract Class<?>[] getServletConfigClasses();// 用于配置 DispatcherServlet 的映射protected abstract String[] getServletMappings();protected void customizeRegistration(ServletRegistration.Dynamic registration) {}
}
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {@Overrideprotected Class<?>[] getRootConfigClasses() {return new Class[] { RootConfig.class };}@Overrideprotected Class<?>[] getServletConfigClasses() {return new Class[] { ServletConfig.class };}@Overrideprotected String[] getServletMappings() {return new String[] { "/" };}
}

这篇关于SpringMVC之DispatcherServlet组件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/776853

相关文章

Java图片压缩三种高效压缩方案详细解析

《Java图片压缩三种高效压缩方案详细解析》图片压缩通常涉及减少图片的尺寸缩放、调整图片的质量(针对JPEG、PNG等)、使用特定的算法来减少图片的数据量等,:本文主要介绍Java图片压缩三种高效... 目录一、基于OpenCV的智能尺寸压缩技术亮点:适用场景:二、JPEG质量参数压缩关键技术:压缩效果对比

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

Java利用docx4j+Freemarker生成word文档

《Java利用docx4j+Freemarker生成word文档》这篇文章主要为大家详细介绍了Java如何利用docx4j+Freemarker生成word文档,文中的示例代码讲解详细,感兴趣的小伙伴... 目录技术方案maven依赖创建模板文件实现代码技术方案Java 1.8 + docx4j + Fr

SpringBoot首笔交易慢问题排查与优化方案

《SpringBoot首笔交易慢问题排查与优化方案》在我们的微服务项目中,遇到这样的问题:应用启动后,第一笔交易响应耗时高达4、5秒,而后续请求均能在毫秒级完成,这不仅触发监控告警,也极大影响了用户体... 目录问题背景排查步骤1. 日志分析2. 性能工具定位优化方案:提前预热各种资源1. Flowable

基于SpringBoot+Mybatis实现Mysql分表

《基于SpringBoot+Mybatis实现Mysql分表》这篇文章主要为大家详细介绍了基于SpringBoot+Mybatis实现Mysql分表的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录基本思路定义注解创建ThreadLocal创建拦截器业务处理基本思路1.根据创建时间字段按年进

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La