AspectJ-结合方法注解和集合字段
AspectJ- combining method annotation and set field
我有一个要求,我需要将各种方法调用计时到时间序列数据库中。
同样,我创建了 2 个注释,其中一个用于方法调用:
@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 注释的原因是,要推送到 influx db 的 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 个条件为真。
我这里哪里做错了?
您的分析是正确的:建议永远不会触发。它只是不能,因为您组合的两个切入点是互斥的:@Auditable
所在的位置(方法调用或执行)是与 set()
不同的连接点。您打算表达的内容如下:"Intercept member variable assignment within the control flow of a method execution." 即你需要 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
我有一个要求,我需要将各种方法调用计时到时间序列数据库中。
同样,我创建了 2 个注释,其中一个用于方法调用:
@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 注释的原因是,要推送到 influx db 的 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 个条件为真。
我这里哪里做错了?
您的分析是正确的:建议永远不会触发。它只是不能,因为您组合的两个切入点是互斥的:@Auditable
所在的位置(方法调用或执行)是与 set()
不同的连接点。您打算表达的内容如下:"Intercept member variable assignment within the control flow of a method execution." 即你需要 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