日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

面试官:给我说一下 Spring MVC 拦截器的原理?

發布時間:2025/3/21 javascript 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 面试官:给我说一下 Spring MVC 拦截器的原理? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

SpringMVC是目前主流的Web MVC框架之一。

攔截器是每個Web框架必備的功能,也是個老生常談的主題了。

本文將分析SpringMVC的攔截器功能是如何設計的,讓讀者了解該功能設計的原理。

重要接口及類介紹

1. HandlerExecutionChain類

由HandlerMethod和Interceptor集合組成的類,會被HandlerMapping接口的getHandler方法獲取。

2. HandlerInterceptor接口

SpringMVC攔截器基礎接口。

3. AbstractHandlerMapping

HandlerMapping的基礎抽象類。

4. AsyncHandlerInterceptor

繼承HandlerInterceptor的接口,額外提供了afterConcurrentHandlingStarted方法,該方法是用來處理異步請求。當Controller中有異步請求方法的時候會觸發該方法。樓主做過測試,異步請求先支持preHandle、然后執行afterConcurrentHandlingStarted。異步線程完成之后執行preHandle、postHandle、afterCompletion。有興趣的讀者可自行研究。

5. HandlerInterceptorAdapter

實現AsyncHandlerInterceptor接口的抽象類,一般我們使用攔截器的話都會繼承這個類。然后復寫相應的方法。

6. WebRequestInterceptor

與HandlerInterceptor接口類似,區別是WebRequestInterceptor的preHandle沒有返回值。還有WebRequestInterceptor是針對請求的,接口方法參數中沒有response。

AbstractHandlerMapping內部的interceptors是個Object類型集合。處理的時候判斷為MappedInterceptor[加入到mappedInterceptors集合中];HandlerInterceptor、WebRequestInterceptor(適配成WebRequestHandlerInterceptorAdapter)[加入到adaptedInterceptors中]

7. MappedInterceptor

一個包括includePatterns和excludePatterns字符串集合并帶有HandlerInterceptor的類。很明顯,就是對于某些地址做特殊包括和排除的攔截器。

8. ConversionServiceExposingInterceptor

默認的標簽初始化的時候會初始化ConversionServiceExposingInterceptor這個攔截器,并被當做構造方法的參數來構造MappedInterceptor。之后會被加入到AbstractHandlerMapping的mappedInterceptors集合中。該攔截器會在每個請求之前往request中丟入ConversionService。主要用于spring:eval標簽的使用。

源碼分析

首先我們看下攔截器的如何被調用的。

Web請求被DispatcherServlet截獲后,會調用DispatcherServlet的doDispatcher方法。

很明顯地看到,在HandlerAdapter處理之后,以及處理完成之后會調用HandlerExecutionChain的方法。

HandlerExecutionChain的applyPreHandle、applyPostHandle、triggerAfterCompletion方法如下:

很明顯,就是調用內部實現HandlerInterceptor該接口集合的各個對應方法。

下面我們看下HandlerExecutionChain的構造過程。

HandlerExecutionChain是從HandlerMapping接口的getHandler方法獲取的。

HandlerMapping的基礎抽象類AbstractHandlerMapping中:

我們看到,HandlerExecutionChain的攔截器是從AbstractHandlerMapping中的adaptedInterceptors和mappedInterceptors屬性中獲取的。

攔截器的配置

清楚了HandlerExecutionChain的攔截器屬性如何構造之后,下面來看下SpringMVC是如何配置攔截器的。

\1. *-dispatcher.xml配置文件中添加 mvc:interceptors配置

<mvc:interceptors><mvc:interceptor><mvc:mapping?path="/**"/><mvc:exclude-mapping?path="/login"/>???<mvc:exclude-mapping?path="/index"/><bean?class="package.interceptor.XXInterceptor"/></mvc:interceptor> </mvc:interceptors>

這里配置的每個mvc:interceptor都會被解析成MappedInterceptor。

其中子標簽<mvc:mapping path="/"/>會被解析成MappedInterceptor的includePatterns屬性;<mvc:exclude-mapping path="/"/>會被解析成MappedInterceptor的excludePatterns屬性;會被解析成MappedInterceptor的interceptor屬性。

mvc:interceptors這個標簽是被InterceptorsBeanDefinitionParser類解析。

\2. 配置RequestMappingHandlerMapping,并配置該bean對應的interceptors集合屬性。這里的interceptors集合是個Object類型的泛型集合。

AbstractHandlerMapping抽象類只暴露了1個攔截器的set方法 -> interceptors。

adaptedInterceptors和mappedInterceptors均沒有暴露set方法,因此我們只能為RequestMappingHandlerMapping配置interceptors屬性。

其實AbstractHandlerMapping內部的initInterceptors方法中,會遍歷interceptors集合,然后判斷各個項是否是MappedInterceptor、HandlerInterceptor、WebRequestInterceptor。

其中MappedInterceptor類型的攔截器會被加到mappedInterceptors集合中,HandlerInterceptor類型的會被加到adaptedInterceptors集合中,WebRequestInterceptor類型的會被適配成WebRequestHandlerInterceptorAdapter加到adaptedInterceptors集合中。

如果讀者配置了:

<mvc:annotation-driven/>

那么配置如下:

<bean?class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"><property?name="interceptors"><bean?class="package.interceptor.XXInterceptor"/></property><property?name="order"?value="-1"/> </bean>

否則,可以去掉order這個屬性的設置。

為什么呢?請參考樓主的另外一篇博客:http://www.cnblogs.com/fangjian0423/p/spring-Ordered-interface.html

一般建議使用第一種方法。

編寫自定義的攔截器

public?class?LoginInterceptor?extends?HandlerInterceptorAdapter?{@Overridepublic?boolean?preHandle(HttpServletRequest?request,?HttpServletResponse?response,Object?handler)?throws?Exception?{//?獲得請求路徑的uriString?uri?=?request.getRequestURI();//?判斷路徑是登出還是登錄驗證,是這兩者之一的話執行Controller中定義的方法if(uri.endsWith("/login/auth")?||?uri.endsWith("/login/out"))?{return?true;}//?進入登錄頁面,判斷session中是否有key,有的話重定向到首頁,否則進入登錄界面if(uri.endsWith("/login/")?||?uri.endsWith("/login"))?{if(request.getSession()?!=?null?&&?request.getSession().getAttribute("loginUser")?!=?null)?{response.sendRedirect(request.getContextPath()?+?"/index");}?else?{return?true;}}//?其他情況判斷session中是否有key,有的話繼續用戶的操作if(request.getSession()?!=?null?&&?request.getSession().getAttribute("loginUser")?!=?null)?{return?true;}//?最后的情況就是進入登錄頁面response.sendRedirect(request.getContextPath()?+?"/login");return?false;}}

登錄Controller:

@Controller @RequestMapping(value?=?"/login") public?class?LoginController?{@RequestMapping(value?=?{"/",?""})public?String?index()?{return?"login";}@RequestMapping("/auth")public?String?auth(@RequestParam?String?username,?HttpServletRequest?req)?{req.getSession().setAttribute("loginUser",?username);return?"redirect:/index";}@RequestMapping("/out")public?String?out(HttpServletRequest?req)?{req.getSession().removeAttribute("loginUser");return?"redirect:/login";}}

*-diapatcher.xml配置:

<mvc:interceptors><mvc:interceptor><mvc:mapping?path="/**"/><bean?class="org.format.demo.interceptor.LoginInterceptor"/></mvc:interceptor> </mvc:interceptors>

PS:我們看到LoginInterceptor里的preHandle方法對于地址“/login/auth”和"/login/out"不處理。

因此,可以寫點配置,少寫帶java代碼。在攔截器配置中添加2個exclude-mapping,并且去掉LoginInterceptor里的

if(uri.endsWith("/login/auth")?||?uri.endsWith("/login/out"))?{return?true; }

配置新增:

<mvc:exclude-mapping?path="/login/out"/> <mvc:exclude-mapping?path="/login/auth"/>

總結

總結了SpringMVC攔截器的原理以及各種配置,像網上很多人會問為什么攔截器執行preHandle方法返回false之后還是會執行afterCompletion方法,其實我們看下源碼就知道了。

關于異步請求方面的攔截器以及第二種配置方法(interceptors集合屬性可加入繼承自HandlerInterceptorAdapter抽象類的類以及實現WebRequestInterceptor接口的類),讀者可自行研究。

總結

以上是生活随笔為你收集整理的面试官:给我说一下 Spring MVC 拦截器的原理?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产干b | 小说肉肉视频 | 97伊人网 | 亚洲第一色网站 | 亚洲深夜在线 | 美日韩丰满少妇在线观看 | 闫嫩的18sex少妇hd | 国产情侣av自拍 | 亚洲国产精品成人综合在线 | 人妻无码中文字幕免费视频蜜桃 | 无码人妻丰满熟妇啪啪网站 | 人人妻人人爽人人澡人人精品 | 在线观看免费人成视频 | 欧美成人r级一区二区三区 中文无码一区二区三区在线观看 | 日韩av一区二区三区 | 男女免费视频 | 992tv在线影院| 日韩欧美国产另类 | 韩国日本在线 | 亚洲精选在线 | 狠狠操网| 一区二区xxx | 日韩在线第一区 | 婷色| 亚洲综合黄色 | 免费a v视频| 久久这里只有精品久久 | 毛片a片免费观看 | 国产91传媒| 欧美韩一区| 操操操操操操 | 少妇捆绑紧缚av | 少妇精品视频一区二区 | 毛片看看 | 99精品人妻无码专区在线视频区 | 天天综合欧美 | 秋霞毛片少妇激情免费 | 欧美大黑bbbbbbbbb在线 | 欧美久久精品一级黑人c片 1000部多毛熟女毛茸茸 | 天天操天天添 | 免费av在 | 91精品国产色综合久久不卡粉嫩 | 色人阁av | 久久r这里只有精品 | 91国产免费观看 | 窝窝视频在线 | 欧美国产日韩在线观看成人 | 无码精品人妻一二三区红粉影视 | 青娱乐国产盛宴 | 亚洲蜜桃精久久久久久久久久久久 | 国产成人在线免费观看 | 亚洲福利专区 | av在线不卡观看 | 亚洲另类色综合网站 | 在线91视频 | 欧美人禽杂交狂配 | 69久久夜色精品国产69 | 国产精品一区二区欧美 | 日本不卡视频一区二区 | 波多野结衣中文字幕在线播放 | 性视频在线播放 | 欧美成人a∨高清免费观看 国产精品999视频 | 欧美一区网站 | 天天艹夜夜 | 蜜臀久久99精品久久久画质超高清 | 性做久久久久久免费观看 | 亚洲网站色 | 91久久久久一区二区 | 午夜网页 | 偷偷操视频| 麻豆传媒网址 | 蜜臀99久久精品久久久久久软件 | 久久综合五月婷婷 | 国产精品久久久久久亚洲影视 | 长篇高h肉爽文丝袜 | 操操操插插插 | ass大乳尤物肉体pics | 欧美偷拍精品 | 成人h视频在线 | 国产免费黄色 | 五月天社区 | 亚洲欧美日韩动漫 | 日韩免费观看 | 欧美一区三区三区高中清蜜桃 | 日韩午夜三级 | 欧美草草| 青草久久网 | 男人天堂欧美 | 都市激情 自拍偷拍 | 亚洲男女网站 | 欧美色图国产精品 | 欧美草比视频 | 卡一卡二在线视频 | 中国极品少妇xxxx做受 | 亚洲韩国精品 | 西西444www大胆无视频 | 一区二区在线视频免费观看 | 性生交大片免费看女人按摩 | 国产精品性爱在线 |