spring mvc核心源码分析

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】

前言

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

spring mvc核心流程图

20191017100379\_1.png

流程说明:

  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. try {
  7. try {
  8. ModelAndView mv = null;
  9. Object dispatchException = null;
  10. try {
  11. //是否文件上传
  12. processedRequest = this.checkMultipart(request);
  13. multipartRequestParsed = processedRequest != request;
  14. //获取handlerExcutionChain
  15. mappedHandler = this.getHandler(processedRequest);
  16. if (mappedHandler == null) {
  17. this.noHandlerFound(processedRequest, response);
  18. return;
  19. }
  20. //获取handlerAdapter
  21. HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
  22. String method = request.getMethod();
  23. boolean isGet = "GET".equals(method);
  24. if (isGet || "HEAD".equals(method)) {
  25. long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
  26. if (this.logger.isDebugEnabled()) {
  27. this.logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
  28. }
  29. if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
  30. return;
  31. }
  32. }
  33. //调用拦截器们的前置方法
  34. if (!mappedHandler.applyPreHandle(processedRequest, response)) {
  35. return;
  36. }
  37. //调用controller里的业务逻辑方法并返回modelAndView
  38. mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
  39. if (asyncManager.isConcurrentHandlingStarted()) {
  40. return;
  41. }
  42. this.applyDefaultViewName(processedRequest, mv);
  43. //调用拦截器的后置方法
  44. mappedHandler.applyPostHandle(processedRequest, response, mv);
  45. } catch (Exception var20) {
  46. dispatchException = var20;
  47. } catch (Throwable var21) {
  48. dispatchException = new NestedServletException("Handler dispatch failed", var21);
  49. }
  50. //把modelAndView交给viewResolver去render视图
  51. this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
  52. } catch (Exception var22) {
  53. this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
  54. } catch (Throwable var23) {
  55. this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
  56. }
  57. } finally {
  58. if (asyncManager.isConcurrentHandlingStarted()) {
  59. if (mappedHandler != null) {
  60. mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
  61. }
  62. } else if (multipartRequestParsed) {
  63. this.cleanupMultipart(processedRequest);
  64. }
  65. }
  66. }
     
  1. 获取handlerExcutionChain对象
  2. protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
  3. if (this.handlerMappings != null) {
  4. Iterator var2 = this.handlerMappings.iterator();
  5. while(var2.hasNext()) {
  6. HandlerMapping hm = (HandlerMapping)var2.next();
  7. if (this.logger.isTraceEnabled()) {
  8. this.logger.trace("Testing handler map [" + hm + "] in DispatcherServlet with name '" + this.getServletName() + "'");
  9. }
  10. HandlerExecutionChain handler = hm.getHandler(request);
  11. if (handler != null) {
  12. return handler;
  13. }
  14. }
  15. }

调用拦截器的前置方法

     
  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. return true;
  13. }

//拦截器的后置方法

     
  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. }

反射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. if (!response.containsHeader("Cache-Control")) {
  18. if (this.getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
  19. this.applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
  20. } else {
  21. this.prepareResponse(response);
  22. }
  23. }
  24. return mav;
  25. }

视图渲染

     
  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. if (mv != null && !mv.wasCleared()) {
  14. this.render(mv, request, response);
  15. if (errorView) {
  16. WebUtils.clearErrorRequestAttributes(request);
  17. }
  18. } else if (this.logger.isDebugEnabled()) {
  19. this.logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + this.getServletName() + "': assuming HandlerAdapter completed request handling");
  20. }
  21. if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
  22. if (mappedHandler != null) {
  23. mappedHandler.triggerAfterCompletion(request, response, (Exception)null);
  24. }
  25. }
  26. }

总结

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


来源:[]()

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » spring mvc核心源码分析

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏