I am writing an aspect logger to write a log whenever any member variable in a given class is accessed.
If I write a specific pointcut for a single variable like below, I am able to get the value of the field.
@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);
}
But my class has a dozen+ variables, and I don't intend on writing specific pointcuts for each of them. So, I want to write something like..
@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???>);
}
But unable to understand how to capture the name and value of the field that is being accessed, in case of a wildcard field access specifier.
Thanx to anyone helping me out on this.
It is actually very simple, and sheltem was right, you can just use Object in the returning type declaration. Here is a little demo showing that it even works for both static and non-static members, as long as they are not declared final:
Driver application:
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;
}
}
Aspect:
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);
}
}
Console output:
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
As you can see, PI and COUNTRY are not intercepted because they are (final) constants.
来源:https://stackoverflow.com/questions/29561306/aspectj-how-to-get-accessed-fields-value-in-a-get-pointcut