拦截器Interceptor
拦截器Interceptor
拦截器是Spring框架中提供的用来动态拦截方法调用的机制,主要是在指定方法调用的前后根据业务需要执行预先定义的代码。
拦截器的快速入门
1). 自定义拦截器
创建HandlerInterceptor接口的实现类,并重写其方法。
- HandlerInterceptor
public interface HandlerInterceptor {//目标方法执行前执行//通过返回值决定是否放行 true:放行 false:不放行default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {return true;}//目标方法执行后执行default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,@Nullable ModelAndView modelAndView) throws Exception {}//视图渲染完后执行(最后执行)default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,@Nullable Exception ex) throws Exception {}}
我们可以根据业务需要重写需要的方法达到在指定方法的前后执行预设代码的逻辑。
- 自定义拦截器 (HandlerInterceptor的实现类)
@Component
public class DemoInterceptor implements HandlerInterceptor {//访问资源前执行 // 通过返回值控制是否访问目标资源 true:放行 false: 不放行@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {log.info("目标方法执行前执行,preHandle...");return true;// true: 放行}//访问资源后执行@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {log.info("目标方法执行后执行,,postHandle...");}//视图渲染后执行@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {log.info("视图渲染完后执行,afterCompletion...");}
}
2). 注册配置拦截器
创建WebMvcConfigurer
的实现类,并重写addIinterceptors
方法。(别忘了将配置类交由IOC容器进行管理)
@Configuration//配置类交由IOC管理
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate DemoInterceptor demoInterceptor;//自定义拦截器//重写addInterceptors@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(demoInterceptor)//注册自定义拦截器.addPathPatterns("/**");//通过链式编程指定拦截路径}
}
向服务器发送请求访问资源,控制台日志输出如下:
- preHandle 中返回true,目标方法执行
- preHandle 中返回false,目标方法不执行
addPathPatterns() 中的拦截路径
需要与过滤器的urlPatterns不同的是,拦截器中/*
仅表示一级路径。
拦截路径 | 含义 |
---|---|
/* | 匹配任意一级路径 |
/** | 任意级路径 |
/path/* | 匹配/path下的一级路径 |
/path/** | 匹配/path下的任意级路径 |
注意:
当定义多个拦截器时,多个拦截器的执行顺序如何?
默认情况下,拦截器的执行顺序取决于其在配置类中
addInterceptor
方法调用的顺序。此外,我们还可以使用@Order
注解为拦截器指定优先级。数值越小,优先级越高,从而确保拦截器按预期顺序执行。
过滤器Filter和拦截器Interceptor的执行流程
- 浏览器的请求访问web服务器的资源时,此时过滤器会先拦截到该请求,只有拦截器放行后才会进入到Spring的环境中,然后交由DispatcherServlet(前端控制器)。
- 再由DispatcherServlet(前端控制器)将请求发往拦截器,拦截器在拦截请求后,执行
preHandle()
方法,只有该方法放行后才会访问对应的资源。 - 在请求到达请求资源(Controller)执行完毕后,再回来执行
postHandle()
和agterCompletion()
,最后返回DispatcherServlet,并最终执行过滤器放行后逻辑将数据相应给浏览器。