I\'d like to create an Inter-Type declaration that declares a (static final) Logger instance inside each class.
The constructor should be passed the enclosing class
You can declare a static member on any single class via inter-type declaration:
public aspect LoggingAspect {
static Logger MyClass.someField = Logger.getLogger(MyClass.class.getName());
}
But this is not very flexible because you need to do it for each single class. I just wanted to mention it.
In order to add something which is not technically but effectively a static member to a class, just use per-type association for your logging aspect:
public aspect LoggingAspect
pertypewithin(org.foo..*) // per-type association
{
Logger logger;
after() : staticinitialization(*) { // run 1x after class-loading
logger = Logger.getLogger(
getWithinTypeName() // type associated with aspect instance
);
}
pointcut logged() : // what to log, e.g. public methods
execution(public * *(..)); // (pointcut could also be abstract
// and refined in sub-aspects)
before() : logged() {
logger.log(...); // logging action
}
}
An example similar to this one - it is a common pattern - can be found in Ramnivas Laddad's excellent book AspectJ in action (2nd edition), chapter 6.2.4. It is also mentioned in the AspectJ documentation.
This answer gives the correct solution, posted below for convenience. Additionally it uses AspectJ annotations which is the preferred notation nowadays.
The developers recently added the annotation API, I presume with the intention of standardising the markup as many other popular libraries like Spring are also doing.
@Aspect("pertypewithin(com.something.*))")
public abstract class TraceAspect {
Logger logger;
@Pointcut
public abstract void traced();
@Pointcut("staticinitialization(*)")
public void staticInit() {
}
@After(value = "staticInit()")
public void initLogger(JoinPoint.StaticPart jps) {
logger = Logger.getLogger(jps.getSignature().getDeclaringTypeName());
}
@Before(value = "traced()")
public void traceThatOne(JoinPoint.StaticPart jps) {
logger.log(jps.getSignature().getName());
}
}