preHandle 调用时间:Controller方法处理之前 执行顺序:链式Intercepter情况下,Intercepter按照声明的顺序一个接一个执行 若返回false,则中断执行,注意:不会进入afterCompletion...备注:postHandle虽然post打头,但post、get方法都能处理 afterCompletion 调用前提:preHandle返回true 调用时间:DispatcherServlet进行视图的渲染之后...HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion
序 本文主要研究一下TransactionSynchronization的invokeAfterCompletion afterCompletion org/springframework/transaction...(int status) { } } afterCompletion方法有入参status,表示事务结束时候的状态,0表示事务已提交,1表示事务已回滚,2表示事务未知;与afterCommit的一个最重要的区别是...afterCompletion的异常会被捕获,不像afterCommit会抛给调用方 invokeAfterCompletion org/springframework/transaction/support.../TransactionSynchronizationUtils.java /** * Actually invoke the {@code afterCompletion} methods of...方法有入参status,表示事务结束时候的状态,0表示事务已提交,1表示事务已回滚,2表示事务未知(一般是JTA相关);与afterCommit的一个最重要的区别是afterCompletion的异常(
③ afterCompletion():这个方法在 DispatcherServlet 完全处理完请求后被调用,可以在该方法中进行一些资源清理的操作。...public class FirstHandlerInterceptor implements HandlerInterceptor { @Override public void afterCompletion...arg2, Exception arg3) throws Exception { System.out.println(this.getClass().getName() + " - afterCompletion...public class FirstHandlerInterceptor implements HandlerInterceptor { @Override public void afterCompletion...com.atguigu.springmvc.interceptors.FirstHandlerInterceptor - afterCompletion 执行顺序图解 ?
(int status) {}}afterCompletion方法有入参status,表示事务结束时候的状态,0表示事务已提交,1表示事务已回滚,2表示事务未知;与afterCommit的一个最重要的区别是...afterCompletion的异常会被捕获,不像afterCommit会抛给调用方invokeAfterCompletionorg/springframework/transaction/support.../TransactionSynchronizationUtils.java/** * Actually invoke the {@code afterCompletion} methods of the...(completionStatus);}catch (Throwable tsex) {logger.error("TransactionSynchronization.afterCompletion...方法有入参status,表示事务结束时候的状态,0表示事务已提交,1表示事务已回滚,2表示事务未知(一般是JTA相关);与afterCommit的一个最重要的区别是afterCompletion的异常(
:处理完视图和模型数据,渲染视图完毕之后执行afterCompletion() # 多个拦截器的执行顺序 若每个拦截器的preHandle()都返回true 此时多个拦截器的执行顺序和拦截器在SpringMVC...的配置文件的配置顺序有关: preHandle()会按照配置的顺序执行,而postHandle()和afterCompletion()会按照配置的反序执行 若某个拦截器的preHandle()返回了false...preHandle()返回false和它之前的拦截器的preHandle()都会执行,postHandle()都不执行,返回false的拦截器之前的拦截器的afterCompletion()会执行 Click...FirstInterceptor--afterCompletion 若FirstInterceptor-preHandle返回True,SecondInterceptor--preHandle返回False...,结果为 FirstInterceptor--preHandle SecondInterceptor--preHandle FirstInterceptor--afterCompletion # 自定义拦截器
interceptor.preHandle(request, response, this.handler)) { // 调用HandlerInterceptor.afterCompletion...(),假如目前有A、B、C三个Interceptor,执行了A和B的preHandle(),在执行C的preHandle()方法时返回false,那么还是执行A和B的afterCompletion(),...而且是先执行B.afterCompletion(),再执行A.afterCompletion()。...interceptor.afterCompletion(request, response, this.handler, ex); } catch (Throwable ex2)...{ logger.error("HandlerInterceptor.afterCompletion threw exception", ex2); } } } } 发布者
afterCompletion:在整个请求处理完毕后进行回调,也就是说视图渲染完毕或者调用方已经拿到响应。...关于 afterConcurrentHandlingStarted 官方文档是这样写的:当处理程序同时执行时,调用而不是postHandle和afterCompletion。...然后执行主方法(自己的controller接口),若中间抛出异常,则跟return false效果一致,不会继续执行postHandle,只会倒序执行afterCompletion方法。...若第三个拦截器的preHandle方法return false,则会执行第二个和第一个的postHandle方法和afterCompletion(postHandle都执行完才会执行这个,也就是页面渲染完数据后...(postHandle和afterCompletion都是倒序执行) HandlerInterceptorAdapter 用来做拦截器还是很方便的,可以用来实现如下应用场景: 日志记录,可以记录请求信息的日志
3位置,调用HandlerExecutionChain的applyPreHandle,如下,逐个调用preHandle方法,只要preHandle返还false,就会你像调用afterCompletion...,由List-5可以看出,afterCompletion中抛出异常,会被Spring框架吞噬,每个HandlerInterceptor的afterCompletion方法中,拿到的异常都是null——看..., response, this.handler, ex); } catch (Throwable ex2) { logger.error("HandlerInterceptor.afterCompletion...图1 如图1所示, 如果执行preHandle的链中抛出异常,那么逆向执行afterCompletion,不会执行postHandle;如果postHandle抛出异常,则逆向执行afterCompletion...如果没有抛出异常,正常情况下,先执行完preHandle链,之后调用controller的方法,之后调用逆向postHandle链,之后逆向执行afterCompletion链,如图1中右边的竖行方向调用所示
/** * Trigger afterCompletion callbacks on the mapped HandlerInterceptors....); } } } 通过上面的代码,我们知道对于拦截器的afterCompletion方法,是反向执行的。...3.6 异常处理 如果在执行doDispatch方法过程中,抛出了异常,在catch模块,都会触发执行afterCompletion方法 ?...如果当前拦截器返回为false,倒序执行所有已经执行了的拦截器的afterCompletion。 (3)如果任何一个拦截器返回false,执行返回,不执行目标方法。...(6)前面的步骤有任何异常都会触发倒序执行afterCompletion方法。 (7)页面成功渲染后,也会倒序执行afterCompletion方法。 ?
在实际应用中,咱们一般都是通过实现 HandlerInterceptor 接口或者继承 HandlerInterceptorAdapter 抽象类,复写 preHandle()、postHandle() 和 afterCompletion...实现 HandlerInterceptor 接口(需要实现三个方法) 在 HandlerInterceptor 接口中,定义了 3 个方法,分别为 preHandle()、postHandle() 和 afterCompletion...afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex...异步线程完成之后执行preHandle、postHandle、afterCompletion。...------- Intercepter2 afterCompletion ------- Intercepter1 页面上正常返回 测试结果2(第一个拦截器的 preHandle 返回 false)
public void beforeCompletion() { } @Override public void afterCommit() { } @Override public void afterCompletion...* @see TransactionSynchronization#afterCompletion(int) * @see TransactionSynchronization#STATUS_COMMITTED...* @see TransactionSynchronization#afterCompletion(int) * @see TransactionSynchronization#STATUS_ROLLED_BACK...* @see TransactionSynchronization#afterCompletion(int) */ AFTER_COMPLETION }
throws Exception { System.out.println("postHandle 方法执行了"); } @Override public void afterCompletion...HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion...*/ default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object...{ } } 思考: 如果有多个拦截器,这时拦截器 1 的 preHandle 方法返回 true,但是拦截器 2 的 preHandle 方法返 回 false,而此时拦截器 1 的 afterCompletion...Exception { System.out.println("拦截器 1:postHandle 方法执行了"); } @Override public void afterCompletion
Object handler, ModelAndView modelAndView) throws Exception; void afterCompletion...response, Object handler) throws Exception; 返回值为 boolean类型,如果返回为 true,就会执行controller方法,并且会将afterCompletion...void afterCompletion( HttpServletRequest request,HttpServletResponse response, Object...handler, Exception ex) throws Exception { System.out.println("==afterCompletion...==被执行了 =FirstInterceptor=afterCompletion==被执行了 preHandle方法是按照配置顺序执行的,而postHandle和afterCompletion方法是按照配置逆序执行的
triggerAfterCompletion 触发afterCompletion执回调的映射HandlerInterceptors。...只会调用afterCompletion执行对于其preHandle调用已成功完成并返回true的拦截器 void triggerAfterCompletion(HttpServletRequest request...this.interceptorIndex; i >= 0; i--) { HandlerInterceptor interceptor = interceptors[i]; try { interceptor.afterCompletion...response, this.handler, ex); } catch (Throwable ex2) { logger.error("HandlerInterceptor.afterCompletion
response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion...afterCompletion:在 DispatcherServlet 完全处理完请求后被调用,可用于清理资源等。...Exception { System.out.println("执行Test1Interceptor postHandle方法-->02"); } @Override public void afterCompletion...) throws Exception { System.out.println("执行Test2Interceptor postHandle方法-->02"); } public void afterCompletion...方法-->03 执行Test1Interceptor afterCompletion方法-->03 通过示例,简单的说多个拦截器执行流程就是先进后出。
response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { } default void afterCompletion...在 HandlerInterceptor 中共有三个方法,每个方法的含义如下: preHandler:进入请求方法之前执行; postHandler:请求方法执行完成之后执行; afterCompletion...拦截器的执行流程 在 preHandle 方法中,它的返回值是 boolean 类型的,它的返回值影响着请求方法,以及 postHandle 和 afterCompletion 的执行...2021-05-05 16:02:08.111 INFO 88509 --- [nio-8081-exec-6] com.example.demo.TestInterceptor : afterCompletion...注意观察输出的顺序,preHandle 方法是按注册顺序进行执行的,而 postHandle 和 afterCompletion 跟注册顺序是相反的。
----视图渲染完毕执行"); } } 拦截器处理请求后结果 可以发现,preHandle执行顺序是跟在配置文件的先后注册顺序执行的,postHandle和AfterCompletion是反过来执行的...----视图渲染完毕执行 FirstInterceptor---afterCompletion----视图渲染完毕执行 在源码中 首先为控制器方法打上断点。...在for循环中的if判断,就是判断返回值是不是false,如果是就会执行当前的afterCompletion方法【就是最后执行的那个方法】,并且返回false终结掉DispatcherServlet中的程序执行...afterCompletion方法的执行也和这个postHandel一样–for循环 多个拦截器(preHandel返回false) 依旧是断点模式,但是是将preHandel返回值变成false。...所以在有多个interceptor被注册后,其中有一个interceptor的preHandel方法的返回值为false,那么在这个拦截器之前注册的拦截器的preHandel方法和afterCompletion
方法运行了"); System.out.println(modelAndView.getViewName()); } @Override public void afterCompletion...handler, Exception ex) throws Exception { System.out.println(this.getClass().getName() + " afterCompletion...方法,最后再执行Zulu拦截器的afterCompletion方法 拦截顺序: 拦截器拦截顺序是按照配置的先后顺序,调整拦截器配置顺序 <!...在Zulu拦截器中返回false,重新启动应用,并点击首页的超链接 根据控制台的输出可以确定,即是Zulu拦截器不放行,但是Delta的afterCompletion方法还是会执行。...已放行了的拦截器的afterCompletion方法总会执行
afterCompletion:在 DispatcherServlet 完全处理完请求后被调用,可用于清理资源等。...Exception { System.out.println("执行postHandle方法-->02"); } @Override public void afterCompletion... System.out.println("执行Test1Interceptor postHandle方法-->02"); } @Override public void afterCompletion...handler, Exception ex) throws Exception { System.out.println("执行Test1Interceptor afterCompletion...方法-->03 执行Test1Interceptor afterCompletion方法-->03 通过示例,简单的说多个拦截器执行流程就是先进后出。
HandlerInterceptor2..afterCompletion.. HandlerInterceptor1..afterCompletion.....HandlerInterceptor1..afterCompletion.....从日志看出第二个拦截器的preHandler方法返回false后第一个拦截器的postHandler没有执行,第二个拦截器的postHandler和afterCompletion没有执行,且controller...总结: preHandle按拦截器定义顺序调用 postHandler按拦截器定义逆序调用 afterCompletion按拦截器定义逆序调用 postHandler在拦截器链内所有拦截器返成功调用 afterCompletion
领取专属 10元无门槛券
手把手带您无忧上云