我有一个要求,我需要将各种方法调用计入时间序列db。
同样,我为方法调用创建了一个注释:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Auditable {
String event();
String entity();
}
和另一个字段
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Id {
String id();
}
我需要@ID注释的原因是,只有在运行时才能知道要推送到流入数据库的id字段。
所以,在我的方法中,会发生类似这样的事情:
@Id
String key;
@Auditable(event="xxx",entity="yyy")
public void methodToBeIntercepted(){
String key = <logic to generate key>;
}
我想要使用的想法是添加注释建议以及字段集建议。
@After("@annotation(auditable) && (set(@<package>.ID java.lang.String sample..*.*) && args(id))")
public void pointcutMethod(Auditable auditable,String id){
}
但是流程永远不会进入pointCutMEthod。如果我将条件改为||然后它进入,但它清楚地表明在任何给定的时间点只有1个条件是真的。
我在这里做错了什么?
答案 0 :(得分:0)
您的分析是正确的:建议永远不会触发。它只是不能,因为你组合的两个切入点是互斥的:@Auditable
是(方法调用或执行)是set()
的不同连接点。您打算表达的内容如下:“在方法执行的 控制流 中拦截成员变量。”即你需要cflow(@annotation(auditable))
。
注释和驱动程序应用程序:
package de.scrum_master.app;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Id {
String id();
}
package de.scrum_master.app;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Auditable {
String event();
String entity();
}
package de.scrum_master.app;
public class Application {
@Id(id = "my ID")
String key;
public static void main(String[] args) {
Application application = new Application();
application.methodToBeIntercepted();
}
@Auditable(event = "xxx", entity = "yyy")
public void methodToBeIntercepted() {
key = "I am the key";
}
}
<强>方面:强>
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import de.scrum_master.app.Auditable;
@Aspect
public class MyAspect {
@After("cflow(@annotation(auditable)) && set(@de.scrum_master.app.Id String de.scrum_master..*.*) && args(id)")
public void pointcutMethod(JoinPoint thisJoinPoint, Auditable auditable, String id) {
System.out.println(thisJoinPoint);
System.out.println(" " + auditable);
System.out.println(" " + id);
}
}
控制台日志:
set(String de.scrum_master.app.Application.key)
@de.scrum_master.app.Auditable(event=xxx, entity=yyy)
I am the key