The order in which the Servlet filter and Spring interceptor are executed
is the filter in order? How do we control the order in which filter is executed? Through Tomcat code analysis, the servlet is called after filter execution is complete, and if multiple filter controls the order of execution, the first thing to do is to configure a parameter in the Web.xml, like order, but find out, the servlet does not have this parameter. Try the configuration of the filter mapping sequence, it is effective, the original filter in the order of the implementation of the test filter mapping in the Web.xml order.
Spring Interceptor is also the order of execution, but interceptor more than one configuration parameter order through which he can also implement interceptor execution sequence. In many scenarios, the order of execution is important, such as cache and transaction interceptor order of execution, it is clear that the cache should be in transaction before, so that the discovery hit without opening the transaction, if transaction in front, Opening a transaction every time even if the cache hits, this is a meaningless East action.
Second, the use of SPRINGMVC interceptor to achieve page performance monitoring (filter can also)
The first step is to find a longer time consuming page to optimize. The use of interceptor can be easily handled. The Interceptor provides Prehandle and Posthandle as well as aftercompletion three methods. Prehandle call Controller specific method before calling, Posthandle after the completion of the specific method call, Aftercompletion complete the page after the render call, so that the entire page rendering complete. That is, when we start the Prehandle record, at the end of the Aftercompletion record time, we can or the entire page. Spring comes with stopwatch tool classes to implement time tracking, and the key point interceptor is not thread-safe. We need to use threadlocal to implement thread safety.
@Override public boolean prehandle (Httpservletrequest request, HttpServletResponse Response, object handler) throws Exception { if (useperformance) { stopwatch stopwatch = new stopwatch (Handler.tostring ()); stopwatchlocal.set (stopwatch); stopwatch.start (Handler.tostring ()); } return true; } @Override public&nbsP;void aftercompletion (httpservletrequest request, httpservletresponse response, object handler, exception  EX) throws exception { if (useperformance) { stopwatch stopwatch = stopwatchlocal.get (); stopwatch.stop (); String currentPath = Request.getrequesturi (); string querystring = request.getquerystring (); querystring = querystring == null ? "": "?" + queryString; Log.info ("Access url path: + currentPath + queryString + ") |time: " + stopwatch.gettotaltimemillis ()); stopwatchlocal.set (null); } } |
If you do not use SPRINGMVC you can use filter to complete:
Stopwatch.start (); Dofilterchain (); Stopwatch.stop (); |
Analysis of the implementation of SPRINGMVC interceptor
The SPRINGMVC interceptor differs from the spring interceptor, SPRINGMVC has a unified portal Dispatcherservlet, all requests are through Dispatcherservlet, So only need to dispatcherservlet on the Dispatcherservlet, there is no agent, at the same time SPRINGMVC management controller also do not have agents. It is not difficult to think that we do some action before performing controller, perform certain actions, render do some action. The SPRINGMVC interceptor corresponds to a three prehandle,posthandle,aftercompletion method. Just write the logic we need in three ways, it's all nonsense, or code.
Handlerinterceptor[] interceptors = mappedhandler.getinterceptors (); if (interceptors != null) { for (int i = 0; i < interceptors.length; i++) { HandlerInterceptor Interceptor = interceptors[i]; //ha.handle is to invoke specific controller before this execution prehandle if (!interceptor.prehandle (Processedrequest, response, mappedhandler.gethandler ()) { triggeraftercompletion (mappedhandler, interceptorindex, processedrequest, Response, null); return; } interceptorIndex = i; } } &nBsp; // actually invoke the handler. mv = ha.handle (Processedrequest, response, mappedhandler.gethandler ()); |
After the call is complete, call render (), and finally execute aftercompletion ().
if (interceptors != null) { for (int i = interceptors.length - 1; i >= 0; i--) { HandlerInterceptor interceptor = interceptors[i]; interceptor.posthandle (processedrequest, response, Mappedhandler.gethandler (), &NBSP;MV); } } } catch (ModelandviewdefiningexcEPTION&NBSP;EX) { Logger.debug ("modelandviewdefiningexception encountered", ex); mv = ex.getmodelandview (); } catch (Exception ex) { Object handler = (Mappedhandler != null ? mappedhandler.gethandler () : null); mv = processhandlerexception ( PROCESSEDREQUEST,&NBSP;RESPONSE,&NBSP;HANDLER,&NBSP;EX); errorView = (mv != null); } // did the handler return a view to render? if (mv != null & & !mv.wascleared ()) { render (Mv, processedrequest, response); if (Errorview) { webutils.clearerrorrequestattributes (Request); } } else { if (logger.isdebugenabled ()) { &Nbsp; logger.debug ("Null modelandview returned to DispatcherServlet with name ' " + getservletname () + "': assuming handleradapter completed request handling"); } } // Trigger after-completion for successful outcome. Triggeraftercompletion (Mappedhandler, interceptorindex, processedrequest, response, null); |