You can either use jp.getTarget()
to get the target instance for a non-static method or simply bind target(targetObject)
to an advice method parameter. I am showing you the latter. Here is my MCVE:
Log4J configuration:
log4j.rootLogger=DEBUG, consoleAppender
log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender
log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.consoleAppender.layout.ConversionPattern=[%t] %-5p %c %x - %m%n
Helper class:
package de.scrum_master.app;
public class Person {}
Driver application class:
package de.scrum_master.app;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Application {
private static Log log = LogFactory.getLog(Application.class);
private Person p = new Person();
public void methodA() {}
public static void main(String[] args) {
Application application = new Application();
application.methodA();
}
}
Aspect:
package de.scrum_master.aspect;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import org.apache.commons.logging.Log;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class MyAspect {
@Before("execution(* methodA()) && target(targetObject)")
public void logMethodExecution(JoinPoint jp, Object targetObject) {
// Filter for static logger, make it accessible and use it for logging
Arrays.stream(targetObject.getClass().getDeclaredFields())
.filter(field -> field.getType().equals(Log.class) && Modifier.isStatic(field.getModifiers()))
.forEach(field -> {
try {
field.setAccessible(true);
((Log) field.get(null)).info(jp + " -> logging using apache commons logger");
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
});
}
}
Console log:
[main] INFO de.scrum_master.app.Application - execution(void de.scrum_master.app.Application.methodA()) -> logging using apache commons logger
This kind of reflection stuff is quite ugly and might not work the way you wish in JMS-style modular applications without configurative precautions, if aspect and target class are not in the same module. At least, you could make your loggers public in order to avoid using field.setAccessible(true)
.