毕设过程中碰到Spring拦截器,不知其原理,特此在此查询总结
一、简介
SpringWebMVC的处理器拦截器,类似于servlet开发中的过滤器Filter,用于处理器进行预处理和后处理。
二、HandlerInterrceptor拦截器常用的用途
(1)日志记录:记录请求信息的日志。以便进行信息监控,信息统计,计算PV等
(2)权限检查:如登录检测,进入处理器检测是否登录,如果没有直接返回到登录页面。
(3)性能监控:有时候系统在某段时间莫名奇妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完记录结束时间,从而得到该请求的处理时间
(4)通用行为:读取Cookie得到的用户信息,并将用户对象放入请求,从而方便后续流程使用。
(5)OpenSessionInView:如Hibernate,在进入处理器打开Session,在完成后关闭Session。
也就是说符合横切关注点的所有功能都可以放入拦截器实现
三、拦截器适配器HandlerInterceptorAdapter
如果实现HandlerInterrceptoe接口的话,三个方法必须实现,不管你需不需要,此时Spring提供一个HandlerInterceptor适配器(种适配器设计模式的实现),允许我们只实现需要的回调方法。
四、DispatcherServlet内部工作机制
//doDispatch方法
//1、处理器拦截器的预处理(正序执行)
HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();
if (interceptors != null) {
for (int i = 0; i < interceptors.length; i++) {
HandlerInterceptor interceptor = interceptors[i];
if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {
//1.1、失败时触发afterCompletion的调用
triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);
return;
}
interceptorIndex = i;//1.2、记录当前预处理成功的索引
}
}
//2、处理器适配器调用我们的处理器
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
//当我们返回null或没有返回逻辑视图名时的默认视图名翻译(详解4.15.5 RequestToViewNameTranslator)
if (mv != null && !mv.hasView()) {
mv.setViewName(getDefaultViewName(request));
}
//3、处理器拦截器的后处理(逆序)
if (interceptors != null) {
for (int i = interceptors.length - 1; i >= 0; i–) {
HandlerInterceptor interceptor = interceptors[i];
interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);
}
}
//4、视图的渲染
if (mv != null && !mv.wasCleared()) {
render(mv, processedRequest, response);
if (errorView) {
WebUtils.clearErrorRequestAttributes(request);
}
//5、触发整个请求处理完毕回调方法afterCompletion
triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);
复制代码
复制代码
// triggerAfterCompletion方法
private void triggerAfterCompletion(HandlerExecutionChain mappedHandler, int interceptorIndex,
HttpServletRequest request, HttpServletResponse response, Exception ex) throws Exception {
// 5、触发整个请求处理完毕回调方法afterCompletion (逆序从1.2中的预处理成功的索引处的拦截器执行)
if (mappedHandler != null) {
HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();
if (interceptors != null) {
for (int i = interceptorIndex; i >= 0; i–) {
HandlerInterceptor interceptor = interceptors[i];
try {
interceptor.afterCompletion(request, response, mappedHandler.getHandler(), ex);
}
catch (Throwable ex2) {
logger.error(“HandlerInterceptor.afterCompletion threw exception”, ex2);
}
}
}
}
}
Spring拦截器——HandlerInterCeptor
最新推荐文章于 2024-07-27 15:07:45 发布