Spring的两种拦截器


目录

  1. Spring拦截器简介
  2. MethodInterceptor的使用

参考文档:

Spring拦截器简介

spring中拦截器主要分两种,一个是HandlerInterceptor,一个是MethodInterceptor

区别

  • HandlerInterceptoer拦截的是请求地址,所以针对请求地址做一些验证、预处理等操作比较合适。当你需要统计请求的响应时间时MethodInterceptor将不太容易做到,因为它可能跨越很多方法或者只涉及到已经定义好的方法中一部分代码。

  • MethodInterceptor利用的是AOP的实现机制,在对一些普通的方法上的拦截HandlerInterceptoer就无能为力了,这时候只能利用AOP的MethodInterceptor。

Tomcat容器处理器

在工作中,大部分都是编写RPC接口,所以会使用MethodInterceptor进行接口前后的处理,比如RPC耗时日志等。

MethodInterceptor的使用

使用Springboot工程进行测试

pom依赖

主要是spring-boot-starter-aop依赖。

<dependencies>
        <!-- 集成web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
    </dependencies>

实现MethodInterceptor接口

注意MethodInterceptor引自aopalliance包!!!

我这里就是实现打印所拦截方法的调用耗时。

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.stereotype.Component;

/**
 * @Author: 小小千千
 * @CreateTime: 2023/2/5
 * @Description: 在接口方法打印耗时日志
 */
@Component
public class MethodRTIntercept implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        long startTs = System.currentTimeMillis();
        try {
            Object proceed = invocation.proceed();
            long endTs = System.currentTimeMillis();
            System.out.println("方法" + invocation.getMethod().getName() + "耗时:" + (endTs - startTs));
            return proceed;
        } catch (Exception e) {
            e.printStackTrace();
            return "error: " + e.getMessage();
        }
    }
}

配置Advisor

MethodInterceptor有点类似实现了具体通知的功能(Advice),所以还需要配置切入点(pointcut),最后最合为一个Advisor

@Configuration
public class InterceptorConfig {
    public static final String traceExecution = "execution(* com.qian.controller..*.*(..))";

    @Bean
    public DefaultPointcutAdvisor defaultPointcutAdvisor() {
        /**创建自定义的方法拦截器*/
        MethodRTIntercept methodRTIntercept = new MethodRTIntercept();
        /**定义切入点Pointcut*/
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(traceExecution);
        /**定义通知Advisor*/
        DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
        advisor.setPointcut(pointcut);
        advisor.setAdvice(methodRTIntercept);
        return advisor;
    }
}

Controller方法验证

@RestController
public class AopTestController {

    @RequestMapping("/aop")
    public String aop(){
        try {
            Thread.sleep(100);
        }catch (Exception e){
            e.printStackTrace();
        }
        return "test";
    }
}

测试结果


文章作者: 小小千千
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 小小千千 !
评论
  目录