Spring 拦截器的使用方式

Spring 拦截器的使用方式

基础拦截器

Spring的拦截器主要针对的是对Controller类的业务进行预处理和后处理。

Sping Framwork 5.0 以后的版本可以直接实现 HandlerInterceptor 接口,HandlerInterceptorAdapter成为一个Deprecated 类,以前的版本继承HandlerInterceptorAdapter抽象类。

HandlerInterceptor接口有三个需要实现的方法。

  • preHandle:预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器;返回值:true表示继续流程(如调用下一个拦截器或处理器);false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应。

  • postHandle:后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。

  • afterCompletion:整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中preHandle返回true的拦截器的afterCompletion。

实现步骤

  1. 定义一个拦截器,实现HandlerInterceptor接口
public class MyInterceptor implements HandlerInterceptor {

    private org.slf4j.Logger log = LoggerFactory.getLogger(MyInterceptor.class);
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        HandlerMethod h = (HandlerMethod) handler;
        // 在这里进行
        this.log.info("拦截器" + h.getBean().getClass().getName());
        return true;
    }
}
  1. 配置拦截器,实现WebMvcConfigurer接口的Java配置类,覆写addInterceptors方法,添加实现的拦截器,加上匹配url的代码
@Configuration // 配置注解
public class MyConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    // 需要注意的是,静态文件夹一定要剔除掉,例如excludePathPatterns( "/css/**", "/js/**")
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
    }
}

AOP拦截器

Aspect是更加精细化的操作,Spring Boot在使用Aspect的时候需要加载格外的依赖Spring Boot Starter AOP地址

/**
 * 需要注意的是必须添加@Aspect、@Component这两个注解。
 */
@Aspect  // 作用是把当前类标识为一个切面供容器读取
@Component  // 作用是把这个类注入到spring容器
public class MyAspect {
    private Logger log = LoggerFactory.getLogger(MyAspect.class);
    // 定义切入点表达式
    @Around("execution(* edu.uzz.demo.controller..*.*(..))")
    public Object handleControllerMethods(ProceedingJoinPoint point) throws Throwable {
        this.log.info("处理之前");
        // 运行具体业务调用
        Object obj = point.proceed(point.getArgs());
        this.log.info("处理之后");
        return obj;
    }
}

相关注解如下:

  • @Aspect:作用是把当前类标识为一个切面供容器读取
  • @Pointcut:Pointcut是植入Advice的触发条件。每个Pointcut的定义包括2部分,一是表达式,二是方法签名。方法签名必须是 public及void型。可以将Pointcut中的方法看作是一个被Advice引用的助记符,因为表达式不直观,因此我们可以通过方法签名的方式为 此表达式命名。因此Pointcut中的方法只需要方法签名,而不需要在方法体内编写实际代码。
  • @Around:环绕增强,相当于MethodInterceptor
  • @AfterReturning:后置增强,相当于AfterReturningAdvice,方法正常退出时执行
  • @Before:标识一个前置增强方法,相当于BeforeAdvice的功能,相似功能的还有
  • @AfterThrowing:异常抛出增强,相当于ThrowsAdvice
  • @After: final增强,不管是抛出异常或者正常退出都会执行

定义切入点表达式

参考文章
例如定义切入点表达式 execution (* com.sample.service.impl….(…))
execution()是最常用的切点函数,其语法如下所示:
整个表达式可以分为五个部分:
1、execution(): 表达式主体。
2、第一个*号:表示返回类型,号表示所有的类型。
3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.sample.service.impl包、子孙包下所有类的方法。
4、第二个
号:表示类名,号表示所有的类。
5、
(…):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。

ProceedingJoinPoint 详解

参考文章

总结

拓展文档:拦截器、过滤器、Aspect区别?看这一篇就够了!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值