Spring AOP 中如何使用 @Pointcut(?) 拦截被 “特定注解” 注解的类中所有的方法?

我定义了一个 Log 注解,然后希望被 @Log 注解的类,它的所有方法的执行,都可以被 Spring 的 AOP 拦截到。

Log 注解:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Log {

    String value() default "";
    
}

LogAdvice:

@Aspect
@Component
public class LogAdvice {

    @Pointcut("@target(ssm.annotation.Log)")
    private void advice() {
    }

    @Before("advice()")
    public void doBefore(JoinPoint jp) {
        String methodInfo = getMethodInfo(jp);
        System.out.println(methodInfo);
    }
    
    ...
}

但是部署 Web 程序的时候,控制台报错了,

Spring:INFO CglibAopProxy: Unable to proxy method [protected final void org.springframework.transaction.support.AbstractPlatformTransactionManager.resume(java.lang.Object,org.springframework.transaction.support.AbstractPlatformTransactionManager$SuspendedResourcesHolder) throws org.springframework.transaction.TransactionException] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.

@Pointcut("@target(ssm.annotation.Log)")

改为

@Pointcut("@annotation(ssm.annotation.Log)")

便不会报错,但是只能在方法上使用 @Log 才可以在 AOP 中拦截到,这意味着要拦截一个类的所有方法,只能在每个方法上都加上这个注解。

请问 @Pointcut(?) 中该如何设置内容,才能实现在类上 @Log,然后该类中所有的方法在执行前都可以被 AOP 拦截到呢?

阅读 37.1k
3 个回答

使用 "@within(ssm.annotation.Log)",可以拦截被 @Log 注解的类的所有方法。

@annotation 这个表达式只能针对方法。
如果要实现你想要的效果,那就得用 @execution(* * *(..)) 切入所有类所有方法。
然后在 切入点逻辑里面判断该类有没有 @Log 注解

` @Pointcut("execution(public com.company..controller...(..))")
private void advice() {}`

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题