Spring MVC执行流程

绝地灬酷狼 2022-01-28 11:59 336阅读 0赞

Spring MVC执行流程

Spring mvc 是控制层框架

DispatherServlet 是一个servlet

1179709-20190415233921655-793756923.png

请求交给dispatcherServlet 进行管理

1179709-20190415234441685-482055569.png

重写了这个doService方法

  1. protected void service(HttpServletRequest req, HttpServletResponse resp)
  2. throws ServletException, IOException
  3. {
  4. String method = req.getMethod(); //判断请求方法
  5. if (method.equals(METHOD_GET)) { //如果是get方法
  6. long lastModified = getLastModified(req);
  7. if (lastModified == -1) {
  8. // servlet doesn't support if-modified-since, no reason
  9. // to go through further expensive logic
  10. doGet(req, resp);
  11. } else {
  12. long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
  13. if (ifModifiedSince < lastModified) {
  14. // If the servlet mod time is later, call doGet()
  15. // Round down to the nearest second for a proper compare
  16. // A ifModifiedSince of -1 will always be less
  17. maybeSetLastModified(resp, lastModified);
  18. doGet(req, resp);
  19. } else {
  20. resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
  21. }
  22. }
  23. } else if (method.equals(METHOD_HEAD)) {
  24. long lastModified = getLastModified(req);
  25. maybeSetLastModified(resp, lastModified);
  26. doHead(req, resp);
  27. } else if (method.equals(METHOD_POST)) {
  28. doPost(req, resp);
  29. } else if (method.equals(METHOD_PUT)) {
  30. doPut(req, resp);
  31. } else if (method.equals(METHOD_DELETE)) {
  32. doDelete(req, resp);
  33. } else if (method.equals(METHOD_OPTIONS)) {
  34. doOptions(req,resp);
  35. } else if (method.equals(METHOD_TRACE)) {
  36. doTrace(req,resp);
  37. } else {
  38. //
  39. // Note that this means NO servlet supports whatever
  40. // method was requested, anywhere on this server.
  41. //
  42. String errMsg = lStrings.getString("http.method_not_implemented");
  43. Object[] errArgs = new Object[1];
  44. errArgs[0] = method;
  45. errMsg = MessageFormat.format(errMsg, errArgs);
  46. resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
  47. }
  48. }

流程:

1 spring mvc 任何请求先交给DispatcherServlet进行管理

  1. @SuppressWarnings("serial")
  2. public class DispatcherServlet extends FrameworkServlet {

2 执行DispatcherServlet的 doService方法 交给doDispatch方法

  1. @Override
  2. protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
  3. try {
  4. doDispatch(request, response);
  5. }

看这个核心的方法:

  1. protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
  2. HttpServletRequest processedRequest = request;
  3. HandlerExecutionChain mappedHandler = null;
  4. boolean multipartRequestParsed = false;
  5. WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
  6. try {
  7. ModelAndView mv = null; //返回给客户端的
  8. Exception dispatchException = null;
  9. try {
  10. processedRequest = checkMultipart(request); //检查上传文件的
  11. multipartRequestParsed = (processedRequest != request);
  12. // Determine handler for the current request.
  13. mappedHandler = getHandler(processedRequest); //获取到HandlerMapping 任何一个请求到这里都可以拿到一个注册信息了 哪个controller 哪个方法
  14. if (mappedHandler == null) {
  15. noHandlerFound(processedRequest, response);
  16. return;
  17. }
  18. // Determine handler adapter for the current request.
  19. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); //适配器 主要做拦截器操作(在方法执行之前执行)
  20. // Process last-modified header, if supported by the handler.
  21. String method = request.getMethod();
  22. boolean isGet = "GET".equals(method); //判断是get请求
  23. if (isGet || "HEAD".equals(method)) {
  24. long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
  25. if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
  26. return;
  27. }
  28. }
  29. if (!mappedHandler.applyPreHandle(processedRequest, response)) {
  30. return;
  31. }
  32. // Actually invoke the handler.
  33. mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); //开始执行 执行完毕获取到当前ModeAndView
  34. if (asyncManager.isConcurrentHandlingStarted()) {
  35. return;
  36. }
  37. applyDefaultViewName(processedRequest, mv);
  38. mappedHandler.applyPostHandle(processedRequest, response, mv);
  39. }
  40. catch (Exception ex) {
  41. dispatchException = ex;
  42. }
  43. catch (Throwable err) {
  44. // As of 4.3, we're processing Errors thrown from handler methods as well,
  45. // making them available for @ExceptionHandler methods and other scenarios.
  46. dispatchException = new NestedServletException("Handler dispatch failed", err);
  47. }
  48. processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
  49. }
  50. catch (Exception ex) {
  51. triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
  52. }
  53. catch (Throwable err) {
  54. triggerAfterCompletion(processedRequest, response, mappedHandler,
  55. new NestedServletException("Handler processing failed", err));
  56. }
  57. finally {
  58. if (asyncManager.isConcurrentHandlingStarted()) {
  59. // Instead of postHandle and afterCompletion
  60. if (mappedHandler != null) {
  61. mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
  62. }
  63. }
  64. else {
  65. // Clean up any resources used by a multipart request.
  66. if (multipartRequestParsed) {
  67. cleanupMultipart(processedRequest);
  68. }
  69. }
  70. }
  71. }

3 doDispatch获取HandlerMapping。表示获取当前的具体的请求信息class地址和方法名称,获取到适配器

4HandlerAdapter 开始拦截

5 执行完毕之后,获取当前ModelAndView

6 执行视图解析

1179709-20190416004243128-893053300.png

1179709-20190416004251124-1480146874.png

Spring**工作流程描述**

  1. 1. 用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet捕获;
  2. 2. DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;
  3. 3. DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。(**附注**:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)方法)
  4. 4. 提取Request中的模型数据,填充Handler入参,开始执行HandlerController)。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
  5. HttpMessageConveter 将请求消息(如Jsonxml等数据)转换成一个对象,将对象转换为指定的响应信息
  6. 数据转换:对请求消息进行数据转换。如String转换成IntegerDouble
  7. 数据根式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
  8. 数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResultError
  9. 5. Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;
  10. 6. 根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet
  11. 7. ViewResolver 结合ModelView,来渲染视图
  12. 8. 将渲染结果返回给客户端。

Spring工作流程描述

  1. 为什么Spring只使用一个Servlet(DispatcherServlet)来处理所有请求?
  2. 详细见J2EE设计模式-前端控制模式
  3. Spring为什么要结合使用HandlerMapping以及HandlerAdapter来处理Handler?
  4. 符合面向对象中的单一职责原则,代码架构清晰,便于维护,最重要的是代码可复用性高。如HandlerAdapter可能会被用于处理多种Handler

posted @ 2019-04-16 00:37 toov5 阅读(…) 评论(…) 编辑 收藏

发表评论

表情:
评论列表 (有 0 条评论,336人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Spring MVC执行流程

    每日一句:每天起床之前有两个选择,要么继续趴下做你没做完的梦,要么起床完成你没完成的梦想。 ![Spring MVC执行流程][Spring MVC]Spring MVC 执