目前,我有以下切入点。
@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();
}
}
}
当我在根级类上添加< code>@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 {}
}
如果你能告诉我如何使用类和春豆来实现它,我将非常感激。
在深入研究了AOP的主题之后,我终于找到了一个可行的解决方案。
最初,我使用以下切入点。
@Aspect
@Component
public static class MyAnnotationAspect {
/**
* Matches the execution of any methods in a type annotated with @MyAnnotation.
*/
@Pointcut("execution(* (@com.test.MyAnnotation *).*(..))")
public void methodInMyAnnotationType() {}
/**
* Matches the execution of any methods annotated with @MyAnnotation.
*/
@Pointcut("execution(@com.test.MyAnnotation * *.*(..))")
public void methodAnnotatedWithMyAnnotation() {}
@Around("methodInMyAnnotationType() || methodAnnotatedWithMyAnnotation()")
public Object aop(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("AOP IS WORKING");
return pjp.proceed;
}
}
我学到的是,只有当我在实际拥有该方法的类上放置@MyAnnotation
时,该方法InMyAnanationType
切入点才有效。但是,如果我将注释放在扩展类 A 的类 B 上,则 AOP 无法截获类 A 中的方法。
我发现的一个潜在的解决方案如下。
@Pointcut("execution(* *(..)) && @this(com.test.MyAnnotation)")
这意味着切入点是针对当前类和父类的所有方法,并且当前类必须用< code>@MyAnnotation进行注释。看起来很有希望。不幸的是,Spring AOP不支持产生< code > UnsupportedPointcutPrimitiveException 的< code>@this切入点原语。
在深入研究this
主题之后,我发现存在target
primitive,并提出了以下解决方案。
@Pointcut("execution(@com.test.MyAnnotation * *.*(..))")
public void annotatedMethod() {}
@Pointcut("execution(* (@com.test.MyAnnotation *).*(..))")
public void annotatedClass() {}
@Pointcut("execution(* *(..)) && target(com.test.MyAnnotable)")
public void implementedInterface() {}
@Around("annotatedMethod() || annotatedClass() || implementedInterface()")
public Object aop(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("AOP IS WORKING");
return pjp.proceed;
}
这意味着切入点适用于当前类和父类中的所有方法。此外,该方法必须使用@MyAnnoation
进行注释,或者包含该方法的类使用@MyAnnoation
进行注释,或者具有该方法的对象必须是标记接口MyAnnote
的实例。它看起来不错并且可以工作。
我的最终类实现如下所示。
@Service
public class ShiftModule {
@Service
public class Annotated extends ShiftModule implements MyAnnotable {}
@Resource
private ShiftModule.Annotated self;
}
附加信息:
在实验过程中,我确实尝试了以下要点。
@Pointcut("@annotation(com.test.MyAnnotation)")
public void annotatedMethod() {}
@Pointcut("@within(com.test.MyAnnotation)")
public void annotatedClass() {}
@Pointcut("target(com.test.MyAnnotable)")
public void implementedInterface() {}
@Around("execution(* *(..)) && (annotatedMethod() || annotatedClass() || implementedInterface()")
public Object aop(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("AOP IS WORKING");
return pjp.proceed;
}
我发现它不适用于带注释的内部接口,这意味着下面的代码将停止工作。AOP方面根本没有任何影响。
@Repository
public interface OrderRepo extends JpaRepository<Order,Long> {
@Repository("annotatedOrderRepo")
@MyAnnotation
public interface Annotated extends OrderRepo {}
}
这不是回答,只是评论太有限,说不出我想说的话。这其实是对OP自己回答的反馈:
>
在Spring AOP中,执行(*(@com.test.MyAnnotation*).*(..))
也可以写成@(com.test.CyAnnotation)
,因为Spring AOP只知道执行连接点。在AspectJ中,您可以添加
execution(@com.test.MyAnnotation**.*(..))
也可以在Spring AOP中写成@annotation(com.test.MyAnnotation)
,因为Spring AOP只知道执行连接点。在AspectJ中,您可以添加
我学到的是,只有当我在实际拥有该方法的类上放置
@MyAnnotation
时,该方法InMyAnanationType
切入点才有效。
当然,因为这是 Java 注释的一般限制。它们永远不会继承到子类,从接口到类或方法,或者从父类方法继承到覆盖子类方法。唯一的例外是,如果您使用
@Inherited
作为注释类型本身的元注释,那么它将被子类继承(但同样不是从接口到实现类)。此处记录了这一点。
至于
切入点中的“target”不同,其中“this“是调用方法,“target“是被调用方法。因为this()
vstarget()
和
call()
call()
在SpringAOP中也不可用,所以支持相应的“this”类型切入点是没有意义的。
如果您愿意切换到AeyJ,我有一个解决方法可以使实现类从接口“继承”注释,并使特定方法也“继承”注释,请参阅此答案。
我只是出于教育目的提到所有这些,而不是为了取代你自己的解决方案,因为你似乎对标记注释和标记界面的混合很满意。
我试图在切入点中检测用注释注释的类的任何方法。 我试过这个: 但它不起作用。我做错了什么? 谢谢
对于用@X注释的类中的方法或用@X注释的方法,我需要一个切入点。我还需要注释对象。如果类和方法都被注释,我更喜欢将方法注释作为参数。 我尝试了以下操作,这会产生“绑定不一致”的警告。(为什么不直接将其设置为null?) 以下内容创建了“穿过切入点中的“||”的参数x的不明确绑定”警告。(在我看来,这不一定有意义:为什么不绑定第一个短路评估?) 如果存在类和方法注释,则将前面的尝试拆分为两个,自然会
我正在研究一个日志方面,它需要截获所有用自定义注释注释的类和方法。 下面是可以在类和方法上注释的自定义注释类: 我使用这些切入点表达式拦截带有注释的方法和类,这适用于所有简单类,但不适用于扩展或实现的类。 但是对而不是调用通知。 当对任何类或方法应用注释时,如何编写同时拦截对任何子类方法调用的切入点表达式?
问题内容: 我需要 在类中使用@X注释的方法或使用@X注释的方法的切入点 。我还 需要注释对象 。如果同时注释了类和方法,则 我更喜欢将方法注释作为参数 。 我尝试了以下操作,这将创建“不一致的绑定”警告。(为什么不将它们设置为null?) 下面创建“跨’||’的参数x的模糊绑定 在切入点”警告。(我认为这并不一定有意义:为什么不绑定第一个短路评估?) 如果存在类和方法注释,则将先前的尝试自然地分
add:如果我将方法存根添加到Fragment2中,就可以开始使用next annotation,但这是一个非常难看的解决方案 解决方案:多亏了@Kriegaex,我找到了解决方案:
我试图在方法注释上创建一个Aeyj切入点,但我总是用不同的方法失败。我使用的是aspectj自动代理(我在Spring上下文中没有配置其他编织)。我的类如下所示: 所以我想知道为什么aspectj不会创建切入点。我设法使用执行(**(…)使其工作抛出一些exc)这对我来说很好,但我仍然想知道我做错了什么。 另外,由于是在接口中定义的,我指定了实现类的注释,有没有办法让它以这种方式工作?其他代理机制