SpringMVC工作原理及源码解析

  • 一:SpringMVC原理图
  • 二:SpringMVC的主要组件
    • 1、前端控制器DispatcherServlet:
    • 2、处理器映射器HandlerMapping:
    • 3、处理器适配器HandlerAdapter:
    • 4、处理器Handler:
    • 5、控制器Controller:
    • 6、视图解析器ViewResolver:
    • 7、视图View
  • 三:Spring MVC的工作流程
  • 四:Spring 如何保证 Controller 并发的安全?
    • 1、SpringMVC一个Controller处理所有用户请求的并发问题
    • 2、Spring并发访问的线程安全性问题

一:SpringMVC原理图

二:SpringMVC的主要组件

1、前端控制器DispatcherServlet:

Spring提供的前端控制器,所有的请求都有经过它来统一分发。在DispatcherServlet将请求分发给Spring Controller之前,需要借助于Spring提供的HandlerMapping定位到具体的Controller。

我们知道Servlet的service方法是被Servlet容器调用的,这个时机是发生的有客户端向servlet请求服务时调用的,而这些都将其委托给DispatcherServlet的doDispatch方法。我们查看其关键代码。

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {HttpServletRequest processedRequest = request;HandlerExecutionChain mappedHandler = null;boolean multipartRequestParsed = false;WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);try {ModelAndView mv = null;Exception dispatchException = null;try {//检查请求是否是multipart(即文件上传),若是进行相关处理processedRequest = checkMultipart(request);multipartRequestParsed = (processedRequest != request);//通过handermapping映射获取HandlerExecutionChain(处理链中包括了interceptor的前置和后置方法)// Determine handler for the current request.mappedHandler = getHandler(processedRequest);if (mappedHandler == null) {noHandlerFound(processedRequest, response);return;}//根据处理器(handler及HandlerExecutionChain)获取处理器适配器(处理器适配器是为了提供统一接口进行后续处理,从而支持多种类型的处理器)// Determine handler adapter for the current request.HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());// Process last-modified header, if supported by the handler.String method = request.getMethod();boolean isGet = "GET".equals(method);if (isGet || "HEAD".equals(method)) {long lastModified = ha.getLastModified(request, mappedHandler.getHandler());if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {return;}}//执行chain中拦截器附加的预处理方法,即preHandle方法                  if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}//适配器统一执行handle方法(适配器统一接口的作用),此处是真正处理业务逻辑的地方// Actually invoke the handler.mv = ha.handle(processedRequest, response, mappedHandler.getHandler());if (asyncManager.isConcurrentHandlingStarted()) {return;}applyDefaultViewName(processedRequest, mv);//执行chain中拦截器附加的后处理方法,即postHandle方法mappedHandler.applyPostHandle(processedRequest, response, mv);}catch (Exception ex) {dispatchException = ex;}catch (Throwable err) {// As of 4.3, we're processing Errors thrown from handler methods as well,// making them available for @ExceptionHandler methods and other scenarios.dispatchException = new NestedServletException("Handler dispatch failed", err);}//处理分发结果:包括解析视图并进行视图渲染,执行chain中拦截器附加的后处理方法,即afterCompletion方法。具体方法内容见下方源码。processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);}catch (Exception ex) {triggerAfterCompletion(processedRequest, response, mappedHandler, ex);}catch (Throwable err) {triggerAfterCompletion(processedRequest, response, mappedHandler,new NestedServletException("Handler processing failed", err));}finally {if (asyncManager.isConcurrentHandlingStarted()) {// Instead of postHandle and afterCompletionif (mappedHandler != null) {mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);}}else {// Clean up any resources used by a multipart request.if (multipartRequestParsed) {cleanupMultipart(processedRequest);}}}}

2、处理器映射器HandlerMapping:

能够完成客户请求到Controller映射。

3、处理器适配器HandlerAdapter:

经过适配调用具体的处理器(Handler,也叫后端控制器),即相应的Controller
将Controller执行结果ModelAndView返回给 DispatcherServlet

4、处理器Handler:

一般来说,Controller是Handler,但Handler不一定是Controller。

例如,HttpRequestHandler,WebRequestHandler,MessageHandler都是可以使用DispatcherServlet的处理程序。 @Controller是执行Web请求并返回视图的处理程序。

简而言之,Handler只是一个术语,它不是一个类或接口。 它可以执行映射。

执行流程都是:
处理映射器通过@Controller注解找到处理器,继而通过@RequestMapping注解找到用户输入的url

5、控制器Controller:

需要为并发用户处理上述请求,因此实现Controller接口时,必须保证线程安全并且可重用。Controller将处理用户请求,这和Struts Action扮演的角色是一致的。一旦Controller处理完用户请求,则返回ModelAndView对象给DispatcherServlet前端控制器,ModelAndView中包含了模型(Model)和视图(View)。从宏观角度考虑,DispatcherServlet是整个Web应用的控制器;从微观考虑,Controller是单个
Http请求处理过程中的控制器,而ModelAndView是Http请求过程中返回的模型(Model)和视图(View)。

6、视图解析器ViewResolver:

Spring提供的视图解析器(ViewResolver)在Web应用中查找View对象,从而将相应结果渲染给客户。

7、视图View

View是一个接口, 它的实现类支持不同的视图类型(jsp,freemarker,pdf等 等)

三:Spring MVC的工作流程

(1)用户发送请求至前端控制器DispatcherServlet;
(2) DispatcherServlet收到请求后,调用HandlerMapping处理器映射器, 请求获取Handle;
(3)处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦 截器(如果有则生成)一并返回给DispatcherServlet;
(4)DispatcherServlet 调用 HandlerAdapter处理器适配器;
(5)HandlerAdapter 经过适配调用具体处理器(Handler,也叫后端控制器);
(6)Handler执行完成返回ModelAndView;
(7)HandlerAdapter将Handler执行结果ModelAndView返回给 DispatcherServlet; (8)DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行 解析;
(9)ViewResolver解析后返回具体View;
(10)DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
(11)DispatcherServlet响应用户。

DispatcherServlet是整个Spring MVC的核心。它负责接收HTTP请求组织协调Spring MVC的各个组成部分。其主要工作有以下三项:

  1. 截获符合特定格式的URL请求。
  2. 初始化DispatcherServlet上下文对应的WebApplicationContext,并将其与业务层、持久化层的 WebApplicationContext建立关联。
  3. 初始化Spring MVC的各个组成组件,并装配到DispatcherServlet中。

四:Spring 如何保证 Controller 并发的安全?

1、SpringMVC一个Controller处理所有用户请求的并发问题

有状态和无状态的对象基本概念:
有状态对象(Stateful Bean),就是有实例变量的对象 ,可以保存数据,是非线程安全的。一般是prototype scope。

无状态对象(Stateless Bean),就是没有实例变量的对象,不能保存数据,是不变类,是线程安全的。一般是singleton scope。

springMVC中,一般Controller、service、DAO层的scope均是singleton;
每个请求都是单独的线程,即使同时访问同一个Controller对象,因为并没有修改Controller对象,相当于针对Controller对象而言,只是读操作,没有写操作,不需要做同步处理。

Service层、Dao层用默认singleton就行,虽然Service类也有dao这样的属性,但dao这些类都是没有状态信息的,也就是 相当于不变(immutable)类,所以不影响。

2、Spring并发访问的线程安全性问题

由于Spring MVC默认是Singleton的,所以会产生一个潜在的安全隐患。根本核心是instance变量保持状态的问题。这意味着每个request过来,系统都会用原有的instance去处理,这样导致了两个结果:
一是我们不用每次创建Controller,
二是减少了对象创建和垃圾收集的时间;

由于只有一个Controller的instance,当多个线程同时调用它的时候,它里面的instance变量就不是线程安全的了,会发生窜数据的问题。当然大多数情况下,我们根本不需要考虑线程安全的问题,比如dao,service等,除非在bean中声明了实例变量。因此,我们在使用spring mvc 的contrller时,应避免在controller中定义实例变量。

SpringMVC工作原理及源码解析相关推荐

  1. 视频教程-YOLOv3目标检测:原理与源码解析-计算机视觉

    YOLOv3目标检测:原理与源码解析 大学教授,美国归国博士.博士生导师:人工智能公司专家顾问:长期从事人工智能.物联网.大数据研究:已发表学术论文100多篇,授权发明专利10多项 白勇 ¥78.00 ...

  2. 【特征匹配】ORB原理与源码解析

    相关 : Fast原理与源码解析 Brief描述子原理与源码解析 Harris原理与源码解析 http://blog.csdn.net/luoshixian099/article/details/48 ...

  3. Redis进阶- Redisson分布式锁实现原理及源码解析

    文章目录 Pre 用法 Redisson分布式锁实现原理 Redisson分布式锁源码分析 redisson.getLock(lockKey) 的逻辑 redissonLock.lock()的逻辑 r ...

  4. spring源码分析第四天------springmvc核心原理及源码分析

    spring源码分析第四天------springmvc核心原理及源码分析 1.基础知识普及 2. SpringMVC请求流程 3.SpringMVC代码流程 4.springMVC源码分析 4.1 ...

  5. PCA-SIFT原理及源码解析

    相关: SIFT原理与源码解析 SURF原理与源码解析 ORB原理与源码解析 FAST原理与源码解析 BRIEF描述子原理与源码解析 Harris原理与源码解析 转载请注明出处:http://blog ...

  6. Spring Boot 核心原理与源码解析 - 目录

    准备重新写 SpringBoot 配置文件解析原理 , 先在这里把要写的内容记下来 Spring Boot 核心原理与源码解析 - 目录 1\何时解析\如何解析 application.propert ...

  7. 【特征匹配】BRIEF特征描述子原理及源码解析

    相关:Fast原理及源码解析 Harris原理及源码解析 SIFT原理及源码解析 SURF原理及源码解析 转载请注明出处: http://blog.csdn.net/luoshixian099/art ...

  8. Redux异步解决方案之Redux-Thunk原理及源码解析

    前段时间,我们写了一篇Redux源码分析的文章,也分析了跟React连接的库React-Redux的源码实现.但是在Redux的生态中还有一个很重要的部分没有涉及到,那就是Redux的异步解决方案.本 ...

  9. Mybatis运行原理及源码解析

    Mybatis源码解析 一.前言 本文旨在mybatis源码解析,将整个mybatis运行原理讲解清楚,本文代码地址: https://github.com/lchpersonal/mybatis-l ...

最新文章

  1. 关于定位的一些知识:
  2. 基于消息队列 RocketMQ 的大型分布式应用上云最佳实践
  3. LeetCode 404. 左叶子之和(Sum of Left Leaves)
  4. python采集_Python3做采集
  5. 用C/C++开发《Photoshop》图像处理软件
  6. Flask中的session操作
  7. 小弟个人学习的过程!!!
  8. 初二的孩子,开学考下滑得很厉害,怎么办?
  9. 不再以讹传讹,GET和POST的真正区别(转)
  10. 利用selenium下载图片,不使用requests和urllib等其他工具
  11. 进阶篇: ramdump分析--9 ram dump文件种类
  12. 【小技巧】2345——今日热点弹窗广告(未完成)
  13. 王给月度BOSS队伍带来什么变化?
  14. cadence allegro - 四层板设置 ……F
  15. 【Spring MVC】Json 前后端合并
  16. 洗牌 --网易有道2017内推编程题
  17. zsh:command not found:conda的解决方法
  18. 数睿数据深度 | 中国软件网对话数睿数据总裁刘超:深挖数据驱动、企业级无代码
  19. python1000以内水仙花数_python 计算1000以内的水仙花数
  20. Discuz论坛邮箱配置

热门文章

  1. 电脑通过手机上网的设置
  2. r7 5800x和r7 3700x选哪个
  3. kubernetes——存储之Volumes配置管理
  4. 深入Vue3源码,看看Vue.use后究竟发生了什么?
  5. Powerpc汇编编译学习笔记
  6. java 元注解 @Retention @Inherited @Documented
  7. 文远知行杯广东工业大学第十六届程序设计竞赛
  8. 2022-2028全球及中国食品加工机械设备行业研究及十四五规划分析报告
  9. pdf压缩大小的简单方法
  10. 达观文本处理助力保险公司保单处理流程自动化,提供保单全生命周期解决方案