生活随笔
收集整理的這篇文章主要介紹了
OncePerRequestFilter-源码解析
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
在spring中,filter都默認(rèn)繼承OncePerRequestFilter,但為什么要這樣呢??
OncePerRequestFilter顧名思義,他能夠確保在一次請(qǐng)求只通過一次filter,而不需要重復(fù)執(zhí)行。
/**
* 過濾器基類,旨在確保每個(gè)請(qǐng)求調(diào)度在任何servlet容器上執(zhí)行一次執(zhí)行。?
* 它提供了一個(gè)帶有HttpServletRequest和HttpServletResponse參數(shù)的{@link #doFilterInternal}方法。
*/
public abstract class OncePerRequestFilter extends GenericFilterBean {//附加到“已過濾”請(qǐng)求屬性的過濾器名稱的后綴。public static final String ALREADY_FILTERED_SUFFIX = ".FILTERED";?//這個(gè)doFilter實(shí)現(xiàn)存儲(chǔ)“已經(jīng)過濾”的請(qǐng)求屬性,如果該屬性已經(jīng)存在,則不進(jìn)行再次過濾。//@see #getAlreadyFilteredAttributeName@Overridepublic final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)throws ServletException, IOException {if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {throw new ServletException("OncePerRequestFilter just supports HTTP requests");}HttpServletRequest httpRequest = (HttpServletRequest) request;HttpServletResponse httpResponse = (HttpServletResponse) response;String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName();boolean hasAlreadyFilteredAttribute = request.getAttribute(alreadyFilteredAttributeName) != null;if (hasAlreadyFilteredAttribute || skipDispatch(httpRequest) || shouldNotFilter(httpRequest)) {// 繼續(xù)而不調(diào)用此過濾器...filterChain.doFilter(request, response);}else {// 調(diào)用這個(gè)過濾器…request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);try {doFilterInternal(httpRequest, httpResponse, filterChain);}finally {// 刪除此請(qǐng)求的“已過濾”請(qǐng)求屬性。request.removeAttribute(alreadyFilteredAttributeName);}}}/*** 返回表明請(qǐng)求已被過濾的請(qǐng)求屬性的名稱。*/protected String getAlreadyFilteredAttributeName() {// 如果沒有可用的過濾器名,則為{@code null}String name = getFilterName();if (name == null) {name = getClass().getName();}return name + ALREADY_FILTERED_SUFFIX;}private boolean skipDispatch(HttpServletRequest request) {if (isAsyncDispatch(request) && shouldNotFilterAsyncDispatch()) {return true;}if (request.getAttribute(WebUtils.ERROR_REQUEST_URI_ATTRIBUTE) != null && shouldNotFilterErrorDispatch(){return true;}return false;}/*** 在Servlet 3.0中引入的調(diào)度器類型{@code javax.servlet.DispatcherType.ASYNC}意味著一個(gè)過濾器可以在一個(gè)請(qǐng)求過程中在多個(gè)線* 程中被調(diào)用。 如果過濾器當(dāng)前在異步分派中執(zhí)行,則此方法返回{true}。*/protected boolean isAsyncDispatch(HttpServletRequest request) {return WebAsyncUtils.getAsyncManager(request).hasConcurrentResult();}/*** 請(qǐng)求處理是否處于異步模式,意味著退出當(dāng)前線程后不會(huì)提交響應(yīng)。*/protected boolean isAsyncStarted(HttpServletRequest request) {return WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted();}/*** 可以在子類中覆蓋自定義過濾控件,返回{true}以避免過濾給定的請(qǐng)求。 默認(rèn)實(shí)現(xiàn)總是返回{@code false}。*/protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {return false;}protected boolean shouldNotFilterAsyncDispatch() {return true;}protected boolean shouldNotFilterErrorDispatch() {return true;}/*** 與{@code doFilter}相同的合同,但保證在單個(gè)請(qǐng)求線程中每個(gè)請(qǐng)求只調(diào)用一次。* /protected abstract void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException;}
?
? ? // GenericFilterBean.class//使這個(gè)過濾器的名稱對(duì)子類可用。類似于GenericServlet的{@code getServletName()}。<p>默認(rèn)使用FilterConfig的過濾器名稱。//如果在Spring應(yīng)用程序上下文中初始化為bean,那么它將返回到bean工廠中定義的bean名稱。@Nullableprotected String getFilterName() {return (this.filterConfig != null ? this.filterConfig.getFilterName() : this.beanName);}?
---------------------?
作者:Pazz楓?
來源:CSDN?
原文:https://blog.csdn.net/baidu_36327010/article/details/80538491?utm_source=copy?
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請(qǐng)附上博文鏈接!
總結(jié)
以上是生活随笔為你收集整理的OncePerRequestFilter-源码解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。