netty springmvc_springmvc源码架构解析之HandlerMapping

说在前面

前期回顾

sharding-jdbc源码解析 更新完毕

spring源码解析 更新完毕

spring-mvc源码解析 更新完毕

spring-tx源码解析 更新完毕

spring-boot源码解析 更新完毕

rocketmq源码解析 更新完毕

dubbbo源码解析 更新完毕

netty源码解析 更新完毕

spring源码架构更新完毕

springmvc源码架构更新中

springboot源码架构计划中

github https://github.com/tianheframe

sharding-jdbc源码解析 更新完毕

rocketmq源码解析 更新完毕

seata 源码解析 更新完毕

dubbo 源码解析 更新完毕

netty 源码解析 更新完毕

源码解析

b4f43fb0fa3c6bcfc36c77d6d96f2626.png

org.springframework.web.servlet.HandlerInterceptor 公共接口HandlerInterceptor,工作流接口,允许定制处理程序执行链。应用程序可以为特定的处理程序组注册任意数量的现有或自定义拦截器,以添加公共预处理行为,而不需要修改每个处理程序实现。在适当的HandlerAdapter触发处理程序本身的执行之前,将调用HandlerInterceptor。此机制可用于大量的预处理方面,例如用于授权检查,或用于语言环境或主题更改等公共处理程序行为。它的主要目的是允许分解出重复的处理程序代码。在异步处理场景中,当主线程退出而不呈现或调用postHandle和afterCompletion回调时,处理程序可能在单独的线程中执行。当并发处理程序执行完成时,请求被发送回去,以便继续呈现模型,并再次调用此契约的所有方法。

通常,拦截器链是为每个HandlerMapping bean定义的,共享其粒度。为了能够将某个拦截器链应用于一组处理程序,需要通过一个HandlerMapping bean映射所需的处理程序。拦截器本身在应用程序上下文中定义为bean,由映射bean定义通过其“拦截器”属性引用(在XML中:的)。HandlerInterceptor基本上类似于Servlet过滤器,但与后者相比,它只允许自定义预处理(带有禁止处理程序本身执行的选项)和自定义后处理。过滤器更强大,例如,它们允许交换传递到链中的请求和响应对象。请注意,过滤器是在web中配置的。应用程序上下文中的HandlerInterceptor。作为基本的指导原则,细粒度处理程序相关的预处理任务是HandlerInterceptor实现的候选任务,特别是分解出来的公共处理程序代码和授权检查。另一方面,筛选器非常适合于请求内容和视图内容处理,比如多部分表单和GZIP压缩。这通常显示当需要将筛选器映射到特定的内容类型(例如图像)或所有请求时。

boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)      throws Exception;

拦截处理程序的执行。在HandlerMapping确定适当的处理程序对象之后调用,但在HandlerAdapter调用处理程序之前调用。DispatcherServlet在执行链中处理一个处理程序,该处理程序由任意数量的拦截器组成,处理程序本身位于执行链的末端。使用此方法,每个拦截器可以决定中止执行链,通常是发送HTTP错误或编写自定义响应。

void postHandle(      HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)      throws Exception;

拦截处理程序的执行。在HandlerAdapter实际调用处理程序之后调用,但在DispatcherServlet呈现视图之前调用。可以通过给定的ModelAndView向视图公开其他模型对象。DispatcherServlet在执行链中处理一个处理程序,该处理程序由任意数量的拦截器组成,处理程序本身位于执行链的末端。通过这种方法,每个拦截器可以对一个执行进行后处理,以执行链的相反顺序应用。

void afterCompletion(      HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)      throws Exception;

请求处理完成后的回调,即呈现视图后的回调。将在处理程序执行的任何结果上调用,从而允许适当的资源清理。注意:只有当这个拦截器的preHandle方法成功完成并返回true时才会被调用!与postHandle方法一样,该方法将在链中的每个拦截器上以相反的顺序调用,因此第一个拦截器将是最后一个被调用的拦截器。

org.springframework.web.servlet.AsyncHandlerInterceptor 使用在异步请求处理启动后调用的回调方法扩展HandlerInterceptor。当一个处理程序启动一个异步请求时,DispatcherServlet在没有调用postHandle和afterCompletion的情况下退出,就像它通常对同步请求所做的那样,因为请求处理的结果(例如ModelAndView)可能还没有准备好,并且将从另一个线程并发生成。在这样的场景中,会调用afterConcurrentHandlingStarted,从而允许实现在将线程释放到Servlet容器之前执行清理线程绑定属性等任务。当异步处理完成时,请求被分派到容器进行进一步处理。在这个阶段,DispatcherServlet调用预句柄、postHandle和afterCompletion。为了区分初始请求和异步处理完成后的后续分派,拦截器可以检查javax.servlet。DispatcherType javax.servlet。ServletRequest是“REQUEST”或“ASYNC”。注意,当异步请求超时或出现网络错误时,HandlerInterceptor实现可能需要执行工作。对于这种情况,Servlet容器不会分派,因此不会调用postHandle和afterCompletion方法。相反,拦截器可以注册以通过WebAsyncManager上的registerCallbackInterceptor和registerDeferredResultInterceptor方法跟踪异步请求。无论异步请求处理是否启动,都可以对来自preHandle的每个请求主动执行此操作。

void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler)      throws Exception;

调用,而不是postHandle和afterCompletion,此时a处理程序正在并发执行。实现可以使用提供的请求和响应,但是应该避免以与处理程序的并发执行冲突的方式修改它们。这种方法的典型用法是清除线程局部变量。

org.springframework.web.servlet.handler.HandlerInterceptorAdapter AsyncHandlerInterceptor接口的抽象适配器类,用于简化仅前/仅后拦截器的实现。

@Override  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)      throws Exception {    return true;  }
@Override  public void postHandle(      HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)      throws Exception {  }
@Override  public void afterCompletion(      HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)      throws Exception {  }
@Override  public void afterConcurrentHandlingStarted(      HttpServletRequest request, HttpServletResponse response, Object handler)      throws Exception {  }

org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor 拦截器,它将配置的ConversionService放在请求范围中,以便在请求处理期间可用。请求属性名为“org.springframe .core.convert”。, ConversionService.class. getname()的值。

private final ConversionService conversionService;

conversionService

@Override  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)      throws ServletException, IOException {    request.setAttribute(ConversionService.class.getName(), this.conversionService);    return true;  }

org.springframework.web.servlet.resource.ResourceUrlProviderExposingInterceptor 将ResourceUrlProvider实例公开为请求属性的拦截器。

@Override  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)      throws Exception {    request.setAttribute(RESOURCE_URL_PROVIDER_ATTR, this.resourceUrlProvider);    return true;  }

org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter 实现Servlet HandlerInterceptor接口并包装底层WebRequestInterceptor的适配器。

private final WebRequestInterceptor requestInterceptor;

requestInterceptor

@Override  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)      throws Exception {    this.requestInterceptor.preHandle(new DispatcherServletWebRequest(request, response));    return true;  }
@Override  public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)      throws Exception {    this.requestInterceptor.postHandle(new DispatcherServletWebRequest(request, response),        (modelAndView != null && !modelAndView.wasCleared() ? modelAndView.getModelMap() : null));  }
  @Override  public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)      throws Exception {    this.requestInterceptor.afterCompletion(new DispatcherServletWebRequest(request, response), ex);  }
@Override  public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) {    if (this.requestInterceptor instanceof AsyncWebRequestInterceptor) {      AsyncWebRequestInterceptor asyncInterceptor = (AsyncWebRequestInterceptor) this.requestInterceptor;      DispatcherServletWebRequest webRequest = new DispatcherServletWebRequest(request, response);      asyncInterceptor.afterConcurrentHandlingStarted(webRequest);    }  }

org.springframework.web.servlet.handler.MappedInterceptor 包含和委托对HandlerInterceptor的调用,以及拦截器应该应用的include(和可选排除)路径模式。还提供匹配逻辑来测试拦截器是否应用于给定的请求路径。MappedInterceptor可以直接注册到任何AbstractHandlerMethodMapping中。此外,通过AbstractHandlerMethodMapping(包括祖先ApplicationContext的)自动检测MappedInterceptor类型的bean,这实际上意味着拦截器在所有处理程序映射中都是“全局”注册的。

private final String[] includePatterns;

includePatterns

private final String[] excludePatterns;

excludePatterns

private final HandlerInterceptor interceptor;

interceptor,这里是适配器模式实现

@Override  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)      throws Exception {    return this.interceptor.preHandle(request, response, handler);  }
@Override  public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,      ModelAndView modelAndView) throws Exception {    this.interceptor.postHandle(request, response, handler, modelAndView);  }
@Override  public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,      Exception ex) throws Exception {    this.interceptor.afterCompletion(request, response, handler, ex);  }

org.springframework.web.servlet.mvc.WebContentInterceptor 检查请求并准备响应的处理程序拦截器。检查支持的方法和所需的会话,并应用指定的CacheControl构建器。拦截器支持的所有设置也可以在AbstractController上设置。这个拦截器主要用于对HandlerMapping映射的一组控制器应用检查和准备。

  @Override  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)      throws ServletException {//    校验方法是否合法    checkRequest(request);    String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);    if (logger.isDebugEnabled()) {      logger.debug("Looking up cache seconds for [" + lookupPath + "]");    }    CacheControl cacheControl = lookupCacheControl(lookupPath);    Integer cacheSeconds = lookupCacheSeconds(lookupPath);    if (cacheControl != null) {      if (logger.isDebugEnabled()) {        logger.debug("Applying CacheControl to [" + lookupPath + "]");      }      applyCacheControl(response, cacheControl);    }    else if (cacheSeconds != null) {      if (logger.isDebugEnabled()) {        logger.debug("Applying CacheControl to [" + lookupPath + "]");      }      applyCacheSeconds(response, cacheSeconds);    }    else {      if (logger.isDebugEnabled()) {        logger.debug("Applying default cache seconds to [" + lookupPath + "]");      }      prepareResponse(response);    }    return true;  }

检查请求方法是否合法,进行缓存处理

@Override  public void postHandle(      HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)      throws Exception {  }
@Override  public void afterCompletion(      HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)      throws Exception {  }

说在最后

本次解析仅代表个人观点,仅供参考。

50bb1cf588cc2064e8b628eafeaa5499.gif

扫码进入技术微信群

97852c0c68698730122de846a48e4e86.pngdf32c31fb8151f1cfaa10bec48e27b2f.png71cfa89b62a04234f446b8202332abd1.png钉钉技术群

6240ee07d195611912604e5191286715.png

qq技术群

0890327718e072e4a743287abcae69e2.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/304906.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

单片微型计算机系统应用和开发特点,单片微机原理与应用(第2版)

单片微机原理与应用(第2版)语音编辑锁定讨论上传视频《单片微机原理与应用(第2版)》是2019年7月机械工业出版社出版的图书,作者是罗印升。书 名单片微机原理与应用(第2版)作 者罗印升ISBN9787111538851定 价42.0元出版社机械工业出版社出版时间2019年7月装…

腾讯牛逼,我酸了!!

阅读本文大概需要8分钟。腾讯这两天搞了个业内爆炸沸腾的事情:全员阳光普照发放100股,解禁期一年。腾讯股价近年来一直在疯狂上涨,100股折合人民币6万多:关键是员工什么都没做,直接拿到价值6万的股票。作用可以说是相当…

如何创建生成非 MFC 项目的自定义 AppWizards

当自定义的应用程序向导生成一个项目时,则它只是不能替换自动创建的.dsp 项目设置文件。 .dsp 文件中的项目设置由假定所有生成的项目为 MFC 项目的内部规则设置。 但是,Visual C 5.0 的新对象模型允许修改工具设置,以便从生成的项目中删除所…

这本造价500万的“黑科技”日历,用377张爆美插画给你365天理想生活

以前,每个人家里, 都挂着一本日历。 爷爷戴着老花镜, 盘看着黄道吉日; 奶奶一字一句, 念叨着每日禁忌; 我们跟着日历过日子, 时光缓慢,记忆清晰。 那时候,日历本上的日子…

后端返回number类型数据_Javascript基础教程之数据类型 (数值 Number)

javascript中想限定一个数的数值,无需限定它是整数还是浮点数型var num1 80 ;var num2 55.51;var num3 -34;var num4 9e5;document.write(num1 " " num2 " " num3 " " num4);//运行结果 80 55.51 -34 900000toExponential(…

在计算机科学中计算是指,在计算机中数值计算是指什么

数值计算指有效使用数字计算机求数学问题近似解的方法与过程,以及由相关理论构成的学科。数值计算主要研究如何利用计算机更好的解决各种数学问题,包括连续系统离散化和离散形方程的求解,并考虑误差、收敛性和稳定性等问题。从数学类型分&…

eladmin代码自动生成_如何让Mybatis自动生成代码

点击上方“Java知音”,选择“置顶公众号”技术文章第一时间送达!作者:阿进的写字台cnblogs.com/homejim/p/9782403.html在使用 mybatis 过程中, 当手写 JavaBean 和 XML 写的越来越多的时候, 就越来越容易出错。这种重…

.NET微服务

前文传送门:什么是云原生?现代云原生设计理念Microservices微服务是一种构建现代应用程序的流行的体系结构,云原生系统拥抱微服务。微服务是由一组(使用共享结构交互的、独立的小块服务)搭建的分布式集,具有以下特征:在…

还是找程序员做老公,最靠谱!

很多MM在选老公的时候,都会选择帅气多金,职业又稳定的男生做老公,像医生啊、律师啊、老师啊这类职业。 但是,你有没有想过? 医生的身边都围着好多护士小姐,而且天天加班是常态,相处的时间太少&a…

京瓷1020怎么打印自检页_[建筑]喷墨打印机如何打印自检页 详细

展开全部喷墨打印机如何打印自检页 介绍 打印自我测试、也称为内部测试,可用来32313133353236313431303231363533e59b9ee7ad9431333332636332验证打印机功能。打印自我测试时打印机无需连接到计算机。为每台打印机列出打印自我测试的说明。 可提式的惠普 Deskjet 1.…

计算机基础知识 pdf答案,计算机基础知识练习 答案版.pdf

计算机基础知识练习(B)1.计算机发展阶段的划分是以( )作为标志的。A)存储器 B)逻辑元件 C)程序设计语言 D)运算速度(A)2.世界上第一台电子计算机所采用的电子元件是( )。A)电子管 B)集成电路 C)晶体管 D)大规模及超大规模集成电路(B)3.第二代计算机使用的电子元件是( )。A)电子…

Win XP2实用的修复工具

个人收藏的三个经典Win XP2实用小工具转载于:https://blog.51cto.com/jinboychen/136639

14个超级牛X的免费开源小工具!

最近整理了一些在用的,感觉还不错的开源小工具,有的仅适用MacOS,但多数跨平台。 Homebrew Homebrew — The missing package manager for macOS:https://brew.sh,Mac上非常好用的包管理工具,很多常见的安装…

站在巨人的肩膀,2020我在使用和涉及到的开源项目

背景要想成为一名软件开发者需要学习各种专业知识、技术与框架。比如算法、数据结构、编程语言、流行框架等。但是要想成为更加出色的软件开发者,你要学习的就不仅仅是专业上的知识了。还要懂得利用巨人的肩膀。这是我2020使用和涉及到的开源项目,希望能…

硬件加速下webview切换闪屏_网页渲染性能优化 —— 性能优化下

博客 有更多精品文章哟。Composite 的优化 终于,我们到了像素管道的末尾。对于这一部分的优化策略,我们可以从为什么需要 Composited Layer(Graphics Layer)来入手。这个问题我们在构建 Graphics Layer Tree 的时候,已…

计算机和网络邻居都不见 了,网上邻居看不到自己和别人电脑怎么办

不少网友都试过,在局域网里面,打开网上邻居,结果里面一台电脑都没有,或者只能看到自己的,看不到其他人的,这是怎么回事呢?学习啦小编在这里教大家如何解决这个问题,希望能帮到大家。…

C# 视频监控系列(6):服务器端——封装API(上)(1)

前言 写系列文章的时候[前言]部分变得无言了&#xff0c;可能来得顺利了点吧: ) 本章中提供的封装均是我用笨办法从<<Hikvision 板卡网络开发包编程手册V4.7>>和<<DS-4000HC、HCS、HC、HF、HS、MD卡的Windows编程指南V4.3>>中拷贝出来并参照VC代码进行…

Python 开发者的 6 个必备库

无论你是正在使用 Python 进行快速开发&#xff0c;还是在为 Python 桌面应用制作原生 UI &#xff0c;或者是在优化现有的 Python 代码&#xff0c;以下这些 Python 项目都是应该使用的。 Python 凭借其易用的特点&#xff0c;已经被工业界和学术界广泛采用。另一方面&#x…

如何在注册表里计算机用户名,可以通过注册表修改电脑的密码 ?怎么做的?

可以通过注册表修改电脑的密码 ?怎么做的?以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;可以通过注册表修改电脑的密码 ?怎么做的?不用怎么麻烦的运行输入cmd在这里输入 user 用户名 密…

c++游戏代码大全_还在学少儿编程?不如来玩工厂编程师,免费学编程逻辑的小游戏...

40000游戏爱好者已加入我们&#xff01;每天推荐好玩游戏&#xff01;加入我们&#xff0c;沐沐带你发现好游戏&#xff01;《工厂编程师》游戏小程序好玩吗&#xff1f;《工厂编程师》小游戏怎么玩&#xff1f;只有你想不到&#xff0c;没有我找不到的好游戏&#xff01;「良心…