MethodInterceptor 是 Spring AOP 中用于环绕通知的核心接口,通过 invoke() 方法控制目标方法执行流程,必须显式调用 invocation.proceed() 才能继续执行,支持修改参数、捕获返回值及异常处理,底层与 @Around 通知等价。

MethodInterceptor 是 Spring AOP 中最常用的拦截器接口,用于在目标方法执行前后、异常时插入自定义逻辑。它属于 org.aopalliance.intercept 包(AOP Alliance 标准),Spring 的 ReflectiveMethodInvocation 在执行代理链时会调用其 invoke() 方法。
核心机制:通过 invoke() 控制方法执行流程
不同于 BeforeAdvice 或 AfterReturningAdvice 等简单通知,MethodInterceptor 能决定是否真正执行目标方法、何时执行、甚至替换返回值或抛出异常:
-
invoke(MethodInvocation invocation)是唯一方法,接收一个MethodInvocation对象 - 必须显式调用
invocation.proceed()才会继续执行后续拦截器或目标方法 - 不调用
proceed()就相当于“阻断”调用;多次调用会重复执行(通常应只调一次) - 可以修改入参(通过
invocation.getArguments())、捕获返回值、处理异常
使用方式:配合 @Aspect 或编程式注册
Spring 推荐用 @Aspect + @Around 实现类似功能,但若需直接实现 MethodInterceptor 接口(例如集成旧框架或定制 ProxyFactory),可按以下方式注册:
- 实现接口,重写
invoke(),在其中调用proceed()并处理结果 - 通过
ProxyFactory添加该拦截器:factory.addAdvice(new MyMethodInterceptor()) - 或在 XML 配置中用
<aop:advisor advice-ref="myInterceptor"/>引用 bean
示例片段:
立即学习“Java免费学习笔记(深入)”;
public class LoggingInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("Before: " + invocation.getMethod().getName());
try {
Object result = invocation.proceed(); // 执行目标方法
System.out.println("After returning: " + result);
return result;
} catch (Exception e) {
System.out.println("Exception caught: " + e.getMessage());
throw e;
}
}
}
与 @Around 的关系:本质相同,API 更简洁
@Around 通知底层就是由 Spring 封装为 MethodInterceptor 实例的。写一个 @Around 方法:
- 参数必须是
ProceedingJoinPoint - 需手动调用
pjp.proceed()(等价于invocation.proceed()) - 返回值、异常处理逻辑和
MethodInterceptor完全一致
所以日常开发中,优先使用 @Around —— 更直观、无需关注代理工厂细节,且支持 SpEL 表达式和注解切点。
注意事项:避免常见陷阱
- 不要在
invoke()中无条件递归调用自身,否则栈溢出 - 确保
proceed()只调用一次,除非你明确需要重试或装饰式执行 - 若拦截的是 JDK 动态代理对象,目标类必须实现接口;CGLIB 代理则支持类代理,但要求目标类不能是
final - 拦截器本身不应有状态(如成员变量),因为 Spring 默认单例复用,多线程下可能引发并发问题


















