AspectJ:如何在 get() 切入点中获取访问字段的值
AspectJ: How to get accessed field's value in a get() pointcut
我正在编写方面记录器,以便在访问给定 class 中的任何成员变量时写入日志。
如果我像下面这样为单个变量写一个特定的切入点,我就能得到该字段的值。
@Pointcut("get(* abc.ThreadPoolService.drMaxTh)")
public void drFields() {}
@AfterReturning(pointcut="drFields()", returning="drMaxTh")
public void afterAccessingdrFields(int drMaxTh) {
LOGGER.info("Accessed the field drMaxTh " + drMaxTh);
}
但是我的 class 有十几个变量,我不打算为每个变量编写特定的切入点。所以,我想写一些像..
@Pointcut("get(* abc.ThreadPoolService.*)")
public void drFields() {}
@AfterReturning(pointcut="drFields()", returning= **????** )
public void afterAccessingdrFields(what should come here???) {
LOGGER.info("Accessed the field drMaxTh " + <and here???>);
}
但无法理解如何在通配符字段访问说明符的情况下捕获正在访问的字段的名称和值。
感谢任何帮助我的人。
其实很简单,sheltem是对的,在返回类型声明中使用Object
就可以了。这是一个小演示,显示它甚至适用于静态和非静态成员,只要它们未声明 [=14=]:
驱动申请:
package de.scrum_master.app;
public class Application {
public static final double PI = Math.PI;
static String producer = "Scrum-Master.de";
private int id = 11;
private String author = "Alexander Kriegisch";
private final String COUNTRY = "Germany";
public static void main(String[] args) {
Object dummy;
Application application = new Application();
// Access static fields
dummy = PI;
dummy = producer;
// Access non-static fields
dummy = application.author;
dummy = application.id;
dummy = application.COUNTRY;
}
}
看点:
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class FieldAccessLogger {
@Pointcut("get(* de.scrum_master.app.Application.*)")
public void fieldAccess() {}
@AfterReturning(pointcut = "fieldAccess()", returning = "field")
public void afterFieldAccess(Object field, JoinPoint thisJoinPoint) {
System.out.println(thisJoinPoint.toLongString());
System.out.println(" " + thisJoinPoint.getSignature().getName());
System.out.println(" " + field);
}
}
控制台输出:
get(static java.lang.String de.scrum_master.app.Application.producer)
producer
Scrum-Master.de
get(private java.lang.String de.scrum_master.app.Application.author)
author
Alexander Kriegisch
get(private int de.scrum_master.app.Application.id)
id
11
如您所见,PI
和 COUNTRY
没有被拦截,因为它们是(最终)常量。
我正在编写方面记录器,以便在访问给定 class 中的任何成员变量时写入日志。
如果我像下面这样为单个变量写一个特定的切入点,我就能得到该字段的值。
@Pointcut("get(* abc.ThreadPoolService.drMaxTh)")
public void drFields() {}
@AfterReturning(pointcut="drFields()", returning="drMaxTh")
public void afterAccessingdrFields(int drMaxTh) {
LOGGER.info("Accessed the field drMaxTh " + drMaxTh);
}
但是我的 class 有十几个变量,我不打算为每个变量编写特定的切入点。所以,我想写一些像..
@Pointcut("get(* abc.ThreadPoolService.*)")
public void drFields() {}
@AfterReturning(pointcut="drFields()", returning= **????** )
public void afterAccessingdrFields(what should come here???) {
LOGGER.info("Accessed the field drMaxTh " + <and here???>);
}
但无法理解如何在通配符字段访问说明符的情况下捕获正在访问的字段的名称和值。
感谢任何帮助我的人。
其实很简单,sheltem是对的,在返回类型声明中使用Object
就可以了。这是一个小演示,显示它甚至适用于静态和非静态成员,只要它们未声明 [=14=]:
驱动申请:
package de.scrum_master.app;
public class Application {
public static final double PI = Math.PI;
static String producer = "Scrum-Master.de";
private int id = 11;
private String author = "Alexander Kriegisch";
private final String COUNTRY = "Germany";
public static void main(String[] args) {
Object dummy;
Application application = new Application();
// Access static fields
dummy = PI;
dummy = producer;
// Access non-static fields
dummy = application.author;
dummy = application.id;
dummy = application.COUNTRY;
}
}
看点:
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class FieldAccessLogger {
@Pointcut("get(* de.scrum_master.app.Application.*)")
public void fieldAccess() {}
@AfterReturning(pointcut = "fieldAccess()", returning = "field")
public void afterFieldAccess(Object field, JoinPoint thisJoinPoint) {
System.out.println(thisJoinPoint.toLongString());
System.out.println(" " + thisJoinPoint.getSignature().getName());
System.out.println(" " + field);
}
}
控制台输出:
get(static java.lang.String de.scrum_master.app.Application.producer)
producer
Scrum-Master.de
get(private java.lang.String de.scrum_master.app.Application.author)
author
Alexander Kriegisch
get(private int de.scrum_master.app.Application.id)
id
11
如您所见,PI
和 COUNTRY
没有被拦截,因为它们是(最终)常量。