SpringMVC执行过程详细讲解

目录
  • SpringMVC常用组件
  • DispatcherServlet初始化过程
  • SpringMVC的执行流程

SpringMVC常用组件

DispatcherServlet:前端控制器,不需要工程师开发,由框架提供

作用:统一处理请求和响应,整个流程控制的中心,由它调用其它组件处理用户的请求

HandlerMapping:处理器映射器,不需要工程师开发,由框架提供

作用:根据请求的url、method等信息查找Handler,即控制器方法

Handler:处理器,需要工程师开发

作用:在DispatcherServlet的控制下Handler对具体的用户请求进行处理

HandlerAdapter:处理器适配器,不需要工程师开发,由框架提供

作用:通过HandlerAdapter对处理器(控制器方法)进行执行

ViewResolver:视图解析器,不需要工程师开发,由框架提供

作用:进行视图解析,得到相应的视图,例如:ThymeleafView、InternalResourceView、

RedirectView

View:视图

作用:将模型数据通过页面展示给用户

DispatcherServlet初始化过程

DispatcherServlet 本质上是一个 Servlet,所以天然的遵循 Servlet 的生命周期。所以宏观上是 Servlet生命周期来进行调度。

初始化WebApplicationContext

所在类:org.springframework.web.servlet.FrameworkServle

protected WebApplicationContext initWebApplicationContext() {
WebApplicationContext rootContext =
WebApplicationContextUtils.getWebApplicationContext(getServletContext());
WebApplicationContext wac = null;
if (this.webApplicationContext != null) {
// A context instance was injected at construction time -> use it
wac = this.webApplicationContext;
if (wac instanceof ConfigurableWebApplicationContext) {
ConfigurableWebApplicationContext cwac =
(ConfigurableWebApplicationContext) wac;
if (!cwac.isActive()) {
// The context has not yet been refreshed -> provide services
such as
// setting the parent context, setting the application context
id, etc
if (cwac.getParent() == null) {
// The context instance was injected without an explicit
parent -> set
// the root application context (if any; may be null) as the
parent
cwac.setParent(rootContext);
}
configureAndRefreshWebApplicationContext(cwac);
}
}
}
if (wac == null) {
// No context instance was injected at construction time -> see if one
// has been registered in the servlet context. If one exists, it is
assumed
// that the parent context (if any) has already been set and that the
// user has performed any initialization such as setting the context id
wac = findWebApplicationContext();
}
if (wac == null) {
// No context instance is defined for this servlet -> create a local one
// 创建WebApplicationContext
wac = createWebApplicationContext(rootContext);
}
if (!this.refreshEventReceived) {
// Either the context is not a ConfigurableApplicationContext with
refresh
// support or the context injected at construction time had already been
// refreshed -> trigger initial onRefresh manually here.
synchronized (this.onRefreshMonitor) {
// 刷新WebApplicationContext
onRefresh(wac);
}
}
if (this.publishContext) {
// Publish the context as a servlet context attribute.
// 将IOC容器在应用域共享
String attrName = getServletContextAttributeName();
getServletContext().setAttribute(attrName, wac);
}
return wac;
}

②创建WebApplicationContext

所在类:org.springframework.web.servlet.FrameworkServlet

protected WebApplicationContext createWebApplicationContext(@Nullable
ApplicationContext parent) {
Class<?> contextClass = getContextClass();
if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass))
{
throw new ApplicationContextException(
"Fatal initialization error in servlet with name '" +
getServletName() +
"': custom WebApplicationContext class [" + contextClass.getName() +
"] is not of type ConfigurableWebApplicationContext");
}
// 通过反射创建 IOC 容器对象
ConfigurableWebApplicationContext wac =
(ConfigurableWebApplicationContext)
BeanUtils.instantiateClass(contextClass);
wac.setEnvironment(getEnvironment());
// 设置父容器
wac.setParent(parent);
String configLocation = getContextConfigLocation();
if (configLocation != null) {
wac.setConfigLocation(configLocation);
}
configureAndRefreshWebApplicationContext(wac);
return wac;
}

③DispatcherServlet初始化策略

FrameworkServlet创建WebApplicationContext后,刷新容器,调用onRefresh(wac),此方法在DispatcherServlet中进行了重写,调用了initStrategies(context)方法,初始化策略,即初始化

DispatcherServlet的各个组件

所在类:org.springframework.web.servlet.DispatcherServlet

protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}

SpringMVC的执行流程

用户向服务器发送请求,请求被SpringMVC 前端控制器 DispatcherServlet捕获。

2) DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI),判断请求URI对应的映射:

a) 不存在

i. 再判断是否配置了mvc:default-servlet-handler

ii. 如果没配置,则控制台报映射查找不到,客户端展示404错误

iii. 如果有配置,则访问目标资源(一般为静态资源,如:JS,CSS,HTML),找不到客户端也会展示404错误

b) 存在则执行下面的流程

3) 根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain执行链对象的形式返回。

4) DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。

5) 如果成功获得HandlerAdapter,此时将开始执行拦截器的preHandler(...)方法【正向】

6) 提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)方法,处理请求。在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:

a) HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息

b) 数据转换:对请求消息进行数据转换。如String转换成Integer、Double等

c) 数据格式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等

d) 数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中

7) Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象。

8) 此时将开始执行拦截器的postHandle(...)方法【逆向】。

9) 根据返回的ModelAndView(此时会判断是否存在异常:如果存在异常,则执行

HandlerExceptionResolver进行异常处理)选择一个适合的ViewResolver进行视图解析,根据Model

和View,来渲染视图。

10) 渲染视图完毕执行拦截器的afterCompletion(...)方法【逆向】。

11) 将渲染结果返回给客户端。

到此这篇关于SpringMVC执行过程详细讲解的文章就介绍到这了,更多相关SpringMVC执行过程内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 浅谈SpringMVC的执行流程

    #简易版 1.客户发送请求经过 DisPatcherServlet 核心过滤器 2.DisPatcherServlet 核心控制器在去找一个或多个HandlerMappering 找到需要处理的Controller 3.DisPatcherServlet 通过HandlerAdapter将请求转发给 Controller 4.Controller 调用业务处理后返回结果给 ModelAndView 5.DisPatcherServlet 找到一个或者多个 ViewResolver 视图解析器 找

  • SpringMVC的执行过程浅析

    前言 通过深入分析Spring源码,我们知道Spring框架包括大致六大模块, 如Web模块,数据库访问技术模块,面向切面模块,基础设施模块,核心容器模块和模块, 其中,在Spring框架的Web模块中,又包含很多前端技术,如SpringMVC,Spring WebSocket,Spring WebPortlet等,在本篇文章中,我们主要分析SpringMVC模块, 在分析SpringMVC技术时,本篇文章将通过解读SpringMVC源码,并通过编译器断点调试追踪,研究Spring核心类的UML

  • Spring SpringMVC在启动完成后执行方法源码解析

    关键字:spring容器加载完毕做一件事情(利用ContextRefreshedEvent事件) 应用场景:很多时候我们想要在某个类加载完毕时干某件事情,但是使用了spring管理对象,我们这个类引用了其他类(可能是更复杂的关联),所以当我们去使用这个类做事情时发现包空指针错误,这是因为我们这个类有可能已经初始化完成,但是引用的其他类不一定初始化完成,所以发生了空指针错误,解决方案如下: 1.写一个类继承spring的ApplicationListener监听,并监控ContextRefresh

  • SpringMVC记录我遇到的坑_AOP注解无效,切面不执行的解决

    AOP注解无效,切面不执行的解决 想做一个api请求日志,想到使用aop,配置过程中遇到了一个坑,aop不起作用, 我的aop是这样的: package com.ljwm.ibei.aspact; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.l

  • Springmvc拦截器执行顺序及各方法作用详解

    实现HandlerInterceptor接口或者继承HandlerInterceptor的子类,比如Spring 已经提供的实现了HandlerInterceptor 接口的抽象类HandlerInterceptorAdapter ,下面讲实现其接口的写法,先看一下这个接口的三个方法. - 方法preHandle: 顾名思义,该方法将在请求处理之前进行调用,在controller之前执行.SpringMVC 中的Interceptor 是链式的调用的,在一个应用中或者说是在一个请求中可以同时存在

  • SpringMvc框架的简介与执行流程详解

    目录 一.SpringMvc框架简介 1.Mvc设计理念 2.SpringMvc简介 二.SpringMvc执行流程 1.流程图解 2.步骤描述 3.核心组件 三.整合Spring框架配置 1.spring-mvc配置 2.Web.xml配置 3.测试接口 4.常用注解说明 四.常见参数映射 1.普通映射 2.指定参数名 3.数组参数 4.Map参数 5.包装参数 6.Rest风格参数 五.源代码地址 一.SpringMvc框架简介 1.Mvc设计理念 M:代表模型Model 模型就是数据,应用

  • SpringMVC拦截器创建配置及执行顺序

    目录 SpringMVC拦截器介绍 一.创建拦截器 二.配置拦截器 设置不需要拦截的请求 三.多个拦截器的执行顺序 SpringMVC拦截器介绍 springMVC 中的拦截器用于拦截控制器方法的执行. 先创建出前置需要的一些条件: <a th:href="@{/testInterceptor}" rel="external nofollow" >测试拦截器</a> 后端: @Controller public class TestContr

  • SpringMVC底层执行流程及原理解析

    一个简单的HelloSpringMVC程序 先在web,xml中注册一个前端控制器(DispatcherServlet) <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  • SpringMVC执行步骤、Model的使用详解

    目录 第一个SpringMvc HelloWorld 无启动类 前端操作 后台执行步骤 第二个SpringMvc项目 项目简介 知识点整合 代码实例:SpringMvc02 SpringMvc对rest风格url的支持 SpringMvc文件上传 SpringMvc文件上传 图解SpringMvc的执行流程 第一个SpringMvc HelloWorld 无启动类 springboot才有启动类 前端操作 访问项目名进入默认主页,显示一个链接 点击链接后请求helloWorld.do跳转另一个j

  • SpringMVC执行过程详细讲解

    目录 SpringMVC常用组件 DispatcherServlet初始化过程 SpringMVC的执行流程 SpringMVC常用组件 DispatcherServlet:前端控制器,不需要工程师开发,由框架提供 作用:统一处理请求和响应,整个流程控制的中心,由它调用其它组件处理用户的请求 HandlerMapping:处理器映射器,不需要工程师开发,由框架提供 作用:根据请求的url.method等信息查找Handler,即控制器方法 Handler:处理器,需要工程师开发 作用:在Disp

  • MySql中sql语句执行过程详细讲解

    目录 前言: sql语句的执行过程: 查询缓存: 分析器: 优化器: 执行器: 总结 前言: 很多人都在使用mysql数据库,但是很少有人能够说出来整个sql语句的执行过程是怎样的,如果不了解执行过程的话,就很难进行sql语句的优化处理,也很难设计出来优良的数据库表结构.这篇文章主要是讲解一下sql语句的执行过程. sql语句的执行过程: 客户端.连接器.分析器.优化器.执行器.存储引擎几个阶段. 连接器的作用:管理链接.权限验证的处理. 分析器的作用:词法分析.语法分析. 优化器的作用:执行计

  • SpringBean和Controller实现动态注册与注销过程详细讲解

    目录 说明 注册和注销工具类 编写测试用例 测试结果 注册Service 注册controller 注销Controller 部分场景下可能需要下载远程jar包,然后注册jar包中的Bean和Controller 说明 这里的Bean 一般特指 Service层的服务类,Controller本质上也是Bean 注册和注销工具类 这里用了一些 hutool的工具类,hutools是一个不错的基础工具集. package cn.guzt.utils; import cn.hutool.extra.s

  • Spring集成Mybatis过程详细讲解

    目录 为啥学习集成Mybatis ORM框架 实现步骤 为啥学习集成Mybatis ORM框架 虽然Spring中提供了JDBCTemplate模块,已经很大程度了解决了JDBC代码的复杂度,但它仍然是和Java代码写在一起的.反观 Mybatis 将 Sql 语句写在配置文件中,使得SQL语句和程序实现了松耦合.而且提供了些许标签,使得SQL可以是动态的.在ORM基础上想要更好的用Spring的DI.AOP.事务处理.Junit支持等实现成果,学会使用 Spring 框架集成 Mybatis

  • Kotlin构造函数与成员变量和init代码块执行顺序详细讲解

    目录 在Kotlin中经常看到主构造函数.成员变量.init代码块(也叫初始化器),它们的执行时机和顺序是什么样的呢?看一下官方的示例: class InitOrderDemo(name: String) { val firstProperty = "First property: $name".also(::println) init { println("First initializer block that prints ${name}") } val se

  • C++双线程调用网络摄像头与多线程调用多摄像头同步执行方法详细讲解

    目录 一.使用双线程调用网络摄像头并执行算法 方法一 方法二 二.使用多线程调用多路摄像头并同步执行多个算法 在调用网络摄像头处理自己的算法时,当解码的速度与算法运行的速度差太多时,会出现类似下面的错误 error while decoding MB 148 4, bytestream 所以需要使用两个线程,一个线程调用摄像头,一个线程用来处理图像. 一.使用双线程调用网络摄像头并执行算法 方法一 #include <iostream> #include <thread> #inc

  • SpringMVC REST风格深入详细讲解

    目录 REST简介 RESTful入门案例 REST快速开发 案例-基于RESTful页面数据交互 REST简介 REST介绍 REST(Representational State Transfer),表现形式状态转换 传统风格资源描述形式 http://localhost/user/getById?id=1 http://localhost/user/saveUser REST风格描述形式 http://localhost/user/1 http://localhost/user 优点 隐藏

  • Java 超详细讲解SpringMVC拦截器

    目录 拦截器(interceptor)的作用 拦截器和过滤器区别 拦截器快速入门 多拦截器操作 拦截器方法说明 本章小结 拦截器(interceptor)的作用 Spring MVC 的 拦截器 类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行 预处理 和 后处理 . 将拦截器按一定的顺序联结成一条链,这条链称为 拦截器链(Interceptor Chain) .在访问被拦截的方 法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用.拦截器也是AOP思想的具体实现.

  • SpringMVC超详细讲解视图和视图解析器

    目录 SpringMVC-视图和视图解析器 1.基本介绍 2.自定义视图 1.为什么要自定义视图 2.自定义视图实例-代码实现 3.自定义视图工作流程小结 自定义视图-小结 自定义视图-工作流程 4.目标方法直接指定转发或重定向 1.使用实例 2.指定请求转发流程-Debug源码 3.指定重定向流程-Debug源码 SpringMVC-视图和视图解析器 1.基本介绍 在 springMVC 中的目标方法最终返回都是一个视图(有各种视图). 返回的视图都会由一个视图解析器来处理 (视图解析器有很多

随机推荐