SpringBoot之Interceptor拦截器注入使用
相关文章:SpringBoot 之AOP切面的使用SpringBoot之Listener注册到Spring容器中的多种方法SpringBoot之Interceptor拦截器注入使用SpringBoot之Filter过滤器的实现及排序问题SpringBoot 之多个过滤器(Filter) ,监听器(Listener),切面(AOP),拦截器(Interceptor)的指定排序问题总结篇springb
相关文章:
SpringBoot 之AOP切面的使用
SpringBoot之Listener注册到Spring容器中的多种方法
SpringBoot之Filter过滤器的实现及排序问题
SpringBoot 之多个过滤器(Filter) ,监听器(Listener),切面(AOP),拦截器(Interceptor)的指定排序问题总结篇
springboot中实现拦截器方式
实现方式
实现HandlerInterceptor接口或者继承HandlerInterceptorAdapter 抽象类
两者区别
HandlerInterceptorAdapter 实现AsyncHandlerInterceptor接口,AsyncHandlerInterceptor接口 继承HandlerInterceptor接口。AsyncHandlerInterceptor接口多了一个afterConcurrentHandlingStarted方法
创建一个拦截器实现HandlerInterceptor接口
在jdk1.8之后,只需要实现自己需要的方法。因为接口有默认实现。
@Component
public class LoginInterceptor implements HandlerInterceptor {
/**
* 预处理回调方法,实现处理器的预处理
* 返回值:true表示继续流程;false表示流程中断,不会继续调用其他的拦截器或处理器
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("方法开始前拦截.........");
//业务代码 返回false或者true
return false;
}
/**
* 后处理回调方法,实现处理器(controller)的后处理,但在渲染视图之前
* 此时我们可以通过modelAndView对模型数据进行处理或对视图进行处理
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("方法返回后拦截.........");
}
/**
* 整个请求处理完毕回调方法,即在视图渲染完毕时回调,
* 如性能监控中我们可以在此记录结束时间并输出消耗时间,
* 还可以进行一些资源清理,类似于try-catch-finally中的finally,
* 但仅调用处理器执行链中
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("方法结束后拦截.........");
}
}
创建一个拦截器继承HandlerInterceptorAdapter类
@Component
public class LoginInterceptor implements HandlerInterceptor {
/**
* 预处理回调方法,实现处理器的预处理
* 返回值:true表示继续流程;false表示流程中断,不会继续调用其他的拦截器或处理器
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("方法开始前拦截.........");
//业务代码 返回false或者true
return false;
}
/**
* 后处理回调方法,实现处理器(controller)的后处理,但在渲染视图之前
* 此时我们可以通过modelAndView对模型数据进行处理或对视图进行处理
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("方法返回后拦截.........");
}
/**
* 整个请求处理完毕回调方法,即在视图渲染完毕时回调,
* 如性能监控中我们可以在此记录结束时间并输出消耗时间,
* 还可以进行一些资源清理,类似于try-catch-finally中的finally,
* 但仅调用处理器执行链中
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("方法结束后拦截.........");
}
/**
* 如果返回一个current类型的变量,会启用一个新的线程。执行完preHandle方法之后立即会调用afterConcurrentHandlingStarted,然后新线程再以次执行
*/
@Override
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("do something.........");
super.afterConcurrentHandlingStarted(request, response, handler);
}
}
创建配置类来管理拦截器,并将之前的拦截器注入其中
两种方式,实现 WebMvcConfigurer 或者继承 WebMvcConfigurationSupport 两者没什么区别,看项目的选择。
@Configuration
public class MvcInterceptorConfig extends WebMvcConfigurationSupport {
@Autowired
private LoginInterceptor loginInterceptor;
@Override
protected void addInterceptors(InterceptorRegistry registry) {
// 多个拦截器组成一个拦截器链
// addPathPatterns 用于添加拦截规则,/**表示拦截所有请求
// excludePathPatterns 用户排除拦截
registry.addInterceptor(loginInterceptor).addPathPatterns("/**")
.excludePathPatterns("/stuInfo/getAllStuInfoA","/account/register");
}
}
多个拦截器执行顺序
多个拦截器的执行顺序按照你的代码代码添加顺序,先添加后执行。
在未设置order方法值时:
registry.addInterceptor(repeatPutInterceptor) // 1
registry.addInterceptor(refererInterceptor) // 2
registry.addInterceptor(loginAuthInterceptor) //3
针对于preHandle 执行顺序为:1->2->3
针对于postHandle执行顺序为:3->2->1
针对于afterCompletion执行顺序为:3->2->1
设置order值时:此时能实现自定义顺序
registry.addInterceptor(repeatPutInterceptor).order(1) // 1
registry.addInterceptor(loginAuthInterceptor).order(3) //2
registry.addInterceptor(refererInterceptor).order(2) // 3
针对于preHandle 执行顺序为:1->3->2
针对于postHandle执行顺序为:2->3->1
针对于afterCompletion执行顺序为:2->3->1
源码出处:InterceptorRegistry类
protected List<Object> getInterceptors() {
return this.registrations.stream()
.sorted(INTERCEPTOR_ORDER_COMPARATOR)
.map(InterceptorRegistration::getInterceptor)
.collect(Collectors.toList());
}
private static final Comparator<Object> INTERCEPTOR_ORDER_COMPARATOR =
OrderComparator.INSTANCE.withSourceProvider(object -> {
if (object instanceof InterceptorRegistration) {
return (Ordered) ((InterceptorRegistration) object)::getOrder;
}
return null;
});
排序问题
添加@order注解,和实现Ordered 接口都无法实现自定义顺序的。只能在配置类中注入拦截器的时候添加order或者使用代码顺序来自定义排序
更多推荐
所有评论(0)