我定义了一个 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 拦截到呢?
回答
使用 "@within(ssm.annotation.Log)",可以拦截被 @Log 注解的类的所有方法。
@annotation 这个表达式只能针对方法。
如果要实现你想要的效果,那就得用 @execution(* * *(..)) 切入所有类所有方法。
然后在 切入点逻辑里面判断该类有没有 @Log 注解
` @Pointcut(“execution(public com.company..controller...(..))”)
private void advice() {}`