gpt4 book ai didi

java - 自定义注释的 Spring AOP 切入点不适用于内部静态类

转载 作者:行者123 更新时间:2023-12-02 00:57:10 26 4
gpt4 key购买 nike

目前,我有以下切入点。

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
@Aspect
@Component
public static class MyAnnotationAspect {
@Pointcut("execution(* (@com.test.MyAnnotation *).*(..))")
public void methodInMyAnnotationType() {}

@Around("methodInMyAnnotationType()")
public Object annotate(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("AOP WORKING");
return pjp.proceed();
}
}
}

当我在根级别类上添加 @MyAnnotation 时,它工作正常,如下所示。

@MyAnnotation
@Service
public class ShiftModule {
@Resource
private ShiftModule self;

/* Executing anything using self.method() triggers the Aspect
* for @MyAnnotation perfectly
*/
}

如果我在内部静态类上添加注释,它也不起作用。

@Service
public class ShiftModule {
@Service
@MyAnnotation
public class AnnotatedShiftModule extends ShiftModule {}

@Resource
private AnnotatedShiftModule self;

/* Executing anything using self.method() does NOT trigger the
* Aspect for @MyAnnotation or even framework's annotations
* like @Async
*/
}

如果我在界面上使用这种技术,它就会起作用。

@Repository
public interface OrderRepo extends JpaRepository<Order,Long> {
@Repository("annotatedOrderRepo")
@MyAnnotation
public interface AnnotatedOrderRepo extends OrderRepo {}
}

如果您能向我展示如何使其与类和 Spring bean 一起使用,我将非常感激。

最佳答案

这不是一个答案,但评论太有限,无法说出我想说的。这其实是反馈给the OP's own answer :

  • execution(* (@com.test.MyAnnotation *).*(..)) 也可以写成更易读的 @within(com.test.MyAnnotation) ) 在 Spring AOP 中,因为 Spring AOP 无论如何都只知道执行连接点。在 AspectJ 中,您可以将 &&execution(* *(..)) 添加到切入点。

  • execution(@com.test.MyAnnotation * *.*(..)) 也可以写成更易读的 @annotation(com.test.MyAnnotation) 在 Spring AOP 中,因为 Spring AOP 无论如何只知道执行连接点。在 AspectJ 中,您可以将 &&execution(* *(..)) 添加到切入点。

  • What I learned is that the methodInMyAnnotationType pointcut will only work if I put @MyAnnotation on the class that actually owns the method.

    当然,因为这是Java注释的一般限制。它们永远不会被继承到子类,从接口(interface)到类或方法,或者从父类方法到覆盖的子类方法。唯一的异常(exception)是,如果您使用 @Inherited 作为注释类型本身的元注释,那么它会被子类继承(但同样不是从接口(interface)到实现类)。这已记录在案here .

  • 至于 this()target() 以及 @this()@target >,正如您所说,“this”版本仅受 AspectJ 支持(您也可以选择在 Spring 应用程序中使用它)。原因是“this”仅与 call() 切入点中的“target”有区别,其中“this”是调用方法,“target”是被调用方法。由于 call() 在 Spring AOP 中也不可用,因此支持相应的“this”类型切入点是没有意义的。

  • 如果您愿意切换到 AspectJ,我有一个解决方法,可以使实现类从接口(interface)“继承”注释,并使特定方法也“继承”注释,请参阅 this answer .

我只是出于教育目的而提及所有这些,而不是为了替换您自己的解决方案,因为您似乎对标记注释和标记界面的组合感到满意。

关于java - 自定义注释的 Spring AOP 切入点不适用于内部静态类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61207990/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com