同一方法同时配置Spring AOP与AspectJ切面仅单个生效问题咨询
问题根因
你的自定义SAOPInterceptor实现错误,中断了Spring AOP的拦截器执行链,和代理创建逻辑、配置遗漏无关。
Spring AOP会把所有匹配目标方法的Advisor按优先级组成拦截器链依次执行,MethodInterceptor的invoke方法中,必须调用methodInvocation.proceed()才能触发下一个拦截器/目标方法执行。你当前代码直接通过method.invoke(methodInvocation.getThis(), methodInvocation.getArguments())反射调用目标方法,完全跳过了拦截链后续的所有节点,所以优先级更低的AspectJ切面没有执行机会。当你移除@SAOPTest注解时,该拦截器不会被触发,AspectJ切面自然可以正常执行。
额外存在的两个代码问题
- 耗时计算逻辑错误:你已经通过
finish = System.currentTimeMillis() - start算出了方法执行耗时,最终打印的却是start - finish,输出结果完全不符合预期 - AspectJ切点写法不规范:
@Pointcut("@annotation(AJTest)")没有写注解的全类名,若切面和注解不在同一包下会出现匹配失败的问题
修复代码
1. 修复SAOPInterceptor
package com.test.company; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class SAOPInterceptor implements MethodInterceptor { @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { System.out.println("Number of parameters " + methodInvocation.getArguments().length); // 调用proceed触发拦截链后续逻辑,禁止直接反射调用目标方法 return methodInvocation.proceed(); } }
2. 修复AspectJ切面的耗时打印逻辑
@Around("aJTest()") public Object profile(ProceedingJoinPoint joinPoint) throws Throwable { final long start = System.currentTimeMillis(); try { return joinPoint.proceed(); } finally { long finish = System.currentTimeMillis() - start; System.out.println("Method execution time: " + finish); } }
可选调整:指定切面执行顺序
如果需要控制两个切面的执行先后,可以通过@Order注解配置优先级,数值越小优先级越高:
- 给
AJTestAspect类添加@Order(1)注解 - 给
springAopTestAdvisorBean方法添加@Order(2)注解
内容的提问来源于stack exchange,提问作者Yegor Saliev
相关产品推荐
相关产品推荐

