Reputation: 3328
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.
Upvotes: 3
Views: 6715
Reputation: 67457
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.
Upvotes: 9