gpt4 book ai didi

java - AspectJ - 尝试包装用一个注释而不是另一个注释注释的方法

转载 作者:行者123 更新时间:2023-11-30 08:04:42 25 4
gpt4 key购买 nike

我想包装所有用@Annotation1注释但不用@Annotation2注释的方法。

到目前为止我已经尝试了3种方法,但都失败了。第一个是切入点表达式。示例:

@Before("@annotation(Annotation1) && !@annotation(Annotation2)")
public void doTheWrapping() {
System.out.println("Wrapped!");
}

此方法会包装用 Annotation1 注释的所有内容,而不管 Annotation2。

第二种方法是手动检测Annotation2,但这似乎也不起作用。

@Before("@annotation(Annotation1)")
public void doTheWrapping(final JoinPoint joinPoint) {
Method method = MethodSignature.class.cast(joinPoint.getSignature()).getMethod();

if (AnnotationUtils.getAnnotation(method, Annotation2.class) == null) {
System.out.println("Wrapped!");
}
}

这会失败,因为 AnnotationUtils.getAnnotations(method) 始终返回 null。它似乎根本不知道方法上的注释。

最后,我尝试使用@Pointcuts。

@Pointcut("execution(@Annotation1 * *(..))")
public void annotatedWithAnnotation1() {}

@Pointcut("execution(@Annotation2 * *(..))")
public void annotatedWithAnnotation2() {}

@Before("annotatedWithAnnotation1() && !annotatedWithAnnotation2()")
public void doTheWrapping() {
System.out.println("Wrapped!");
}

这又是一次,无论 Annotation2 如何,都会包装所有内容。

有人可以帮忙吗?

解决方案事实证明答案真的非常简单。将 @Annotation2 移动到接口(interface)而不是实现解决了这个问题。

最佳答案

只要该方面与两个注释位于同一包中,您的第一个切入点就应该可以工作。否则,您需要指定完全限定的类名。这是一个独立的 AspectJ 示例。 Spring AOP 中应该是一样的:

package de.scrum_master.app;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface Annotation1 {}
package de.scrum_master.app;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface Annotation2 {}
package de.scrum_master.app;

public class Application {
@Annotation1
public void foo() {}

@Annotation2
public void bar() {}

@Annotation1
@Annotation2
public void zot() {}

public void baz() {}

public static void main(String[] args) {
Application application = new Application();
application.foo();
application.bar();
application.zot();
application.bar();
}
}
package de.scrum_master.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class MyAspect {
@Before("@annotation(de.scrum_master.app.Annotation1) && !@annotation(de.scrum_master.app.Annotation2)")
public void doTheWrapping(JoinPoint thisJoinPoint) {
System.out.println(thisJoinPoint);
}
}

AspectJ 的控制台输出:

call(void de.scrum_master.app.Application.foo())
execution(void de.scrum_master.app.Application.foo())

Spring AOP 的控制台输出:

因为 Spring AOP 不支持 call() 切入点,所以只要类 Application 存在,就只会拦截 execution() 连接点Spring @Component:

execution(void de.scrum_master.app.Application.foo())

关于java - AspectJ - 尝试包装用一个注释而不是另一个注释注释的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31306528/

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