目录
- Spring拦截器简介
- MethodInterceptor的使用
参考文档:
Spring拦截器简介
spring中拦截器主要分两种,一个是HandlerInterceptor
,一个是MethodInterceptor
。
区别:
HandlerInterceptoer拦截的是请求地址,所以针对请求地址做一些验证、预处理等操作比较合适。当你需要统计请求的响应时间时MethodInterceptor将不太容易做到,因为它可能跨越很多方法或者只涉及到已经定义好的方法中一部分代码。
MethodInterceptor利用的是AOP的实现机制,在对一些普通的方法上的拦截HandlerInterceptoer就无能为力了,这时候只能利用AOP的MethodInterceptor。
在工作中,大部分都是编写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";
}
}