spring mvc核心源码分析

前言

自研究了spring security核心源码以来,在实践使用的基础上更为深入的学习了它的思想.我的java世界仿佛被打开了一扇大门,开始对研究源码有种渴望.打算先看一轮核心源码,满足目前工作需要,待对boot有个整体的了解之后再逐个细细研究

spring mvc核心流程图

《spring mvc核心源码分析》

流程说明:

  1. 用户发送请求到dispatcherServlet,它执行父类frameworkServlet的service方法,service()->processRequest()开始处理请求,processRequest()->doService()->doDispatch();这一段都是给request里加入一些spring的bean,然后处理一下request
  2. dispatcherServlet遍历自己的handlerMapping,当正确的handlerMapping找到handlerExcutionChain的时候返回,给dispatchServlet.(chain里主要是一个handlerAdapter和一些拦截器)
  3. handlerExcutionChain开始拦截器处理请求,然后调用handlerAdapter里的handler()方法,handler()->AbstractHandlerMethodAdapter里的handleInternal(),然后反射执行我们controller里的业务逻辑,将得到的modelAndView对象返回给dispatchServlet,然后继续执行拦截器方法.
  4. dispacherServlet  调用processDispatchResult把得到的modelAndView交给viewResolve去render视图

源码一览


 
  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.  
  7. try {

  8. try {

  9. ModelAndView mv = null;

  10. Object dispatchException = null;

  11.  
  12. try {

  13. //是否文件上传

  14. processedRequest = this.checkMultipart(request);

  15. multipartRequestParsed = processedRequest != request;

  16.   //获取handlerExcutionChain

  17. mappedHandler = this.getHandler(processedRequest);

  18. if (mappedHandler == null) {

  19. this.noHandlerFound(processedRequest, response);

  20. return;

  21. }

  22. //获取handlerAdapter

  23. HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());

  24. String method = request.getMethod();

  25. boolean isGet = "GET".equals(method);

  26. if (isGet || "HEAD".equals(method)) {

  27. long lastModified = ha.getLastModified(request, mappedHandler.getHandler());

  28. if (this.logger.isDebugEnabled()) {

  29. this.logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);

  30. }

  31.  
  32. if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {

  33. return;

  34. }

  35. }

  36. //调用拦截器们的前置方法

  37. if (!mappedHandler.applyPreHandle(processedRequest, response)) {

  38. return;

  39. }

  40. //调用controller里的业务逻辑方法并返回modelAndView

  41. mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

  42. if (asyncManager.isConcurrentHandlingStarted()) {

  43. return;

  44. }

  45.  
  46. this.applyDefaultViewName(processedRequest, mv);

  47.   //调用拦截器的后置方法

  48. mappedHandler.applyPostHandle(processedRequest, response, mv);

  49. } catch (Exception var20) {

  50. dispatchException = var20;

  51. } catch (Throwable var21) {

  52. dispatchException = new NestedServletException("Handler dispatch failed", var21);

  53. }

  54. //把modelAndView交给viewResolver去render视图

  55. this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);

  56. } catch (Exception var22) {

  57. this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);

  58. } catch (Throwable var23) {

  59. this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));

  60. }

  61.  
  62. } finally {

  63. if (asyncManager.isConcurrentHandlingStarted()) {

  64. if (mappedHandler != null) {

  65. mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);

  66. }

  67. } else if (multipartRequestParsed) {

  68. this.cleanupMultipart(processedRequest);

  69. }

  70.  
  71. }

  72. }


 
  1. 获取handlerExcutionChain对象

  2. protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {

  3. if (this.handlerMappings != null) {

  4. Iterator var2 = this.handlerMappings.iterator();

  5.  
  6. while(var2.hasNext()) {

  7. HandlerMapping hm = (HandlerMapping)var2.next();

  8. if (this.logger.isTraceEnabled()) {

  9. this.logger.trace("Testing handler map [" + hm + "] in DispatcherServlet with name '" + this.getServletName() + "'");

  10. }

  11.  
  12. HandlerExecutionChain handler = hm.getHandler(request);

  13. if (handler != null) {

  14. return handler;

  15. }

  16. }

  17. }

调用拦截器的前置方法


 
  1. boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {

  2. HandlerInterceptor[] interceptors = this.getInterceptors();

  3. if (!ObjectUtils.isEmpty(interceptors)) {

  4. for(int i = 0; i < interceptors.length; this.interceptorIndex = i++) {

  5. HandlerInterceptor interceptor = interceptors[i];

  6. if (!interceptor.preHandle(request, response, this.handler)) {

  7. this.triggerAfterCompletion(request, response, (Exception)null);

  8. return false;

  9. }

  10. }

  11. }

  12.  
  13. return true;

  14. }

//拦截器的后置方法


 
  1. void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) throws Exception {

  2. HandlerInterceptor[] interceptors = this.getInterceptors();

  3. if (!ObjectUtils.isEmpty(interceptors)) {

  4. for(int i = interceptors.length - 1; i >= 0; --i) {

  5. HandlerInterceptor interceptor = interceptors[i];

  6. interceptor.postHandle(request, response, this.handler, mv);

  7. }

  8. }

  9.  
  10. }

反射controller我们写的逻辑


 
  1. protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

  2. this.checkRequest(request);

  3. ModelAndView mav;

  4. if (this.synchronizeOnSession) {

  5. HttpSession session = request.getSession(false);

  6. if (session != null) {

  7. Object mutex = WebUtils.getSessionMutex(session);

  8. synchronized(mutex) {

  9. mav = this.invokeHandlerMethod(request, response, handlerMethod);

  10. }

  11. } else {

  12. mav = this.invokeHandlerMethod(request, response, handlerMethod);

  13. }

  14. } else {

  15. mav = this.invokeHandlerMethod(request, response, handlerMethod);

  16. }

  17.  
  18. if (!response.containsHeader("Cache-Control")) {

  19. if (this.getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {

  20. this.applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);

  21. } else {

  22. this.prepareResponse(response);

  23. }

  24. }

  25.  
  26. return mav;

  27. }

视图渲染


 
  1. private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv, @Nullable Exception exception) throws Exception {

  2. boolean errorView = false;

  3. if (exception != null) {

  4. if (exception instanceof ModelAndViewDefiningException) {

  5. this.logger.debug("ModelAndViewDefiningException encountered", exception);

  6. mv = ((ModelAndViewDefiningException)exception).getModelAndView();

  7. } else {

  8. Object handler = mappedHandler != null ? mappedHandler.getHandler() : null;

  9. mv = this.processHandlerException(request, response, handler, exception);

  10. errorView = mv != null;

  11. }

  12. }

  13.  
  14. if (mv != null && !mv.wasCleared()) {

  15. this.render(mv, request, response);

  16. if (errorView) {

  17. WebUtils.clearErrorRequestAttributes(request);

  18. }

  19. } else if (this.logger.isDebugEnabled()) {

  20. this.logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + this.getServletName() + "': assuming HandlerAdapter completed request handling");

  21. }

  22.  
  23. if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {

  24. if (mappedHandler != null) {

  25. mappedHandler.triggerAfterCompletion(request, response, (Exception)null);

  26. }

  27.  
  28. }

  29. }

总结

springmvc核心并不复杂,主要是围绕dispatcherServlet,请朋友们自动动手debugger,这样学习才会更有效

    原文作者:Spring Boot
    原文地址: https://blog.csdn.net/qq_40285302/article/details/82625081
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞