When creating aspects using the Aspect annotation as described here, is it possible to use this annotation with a class that contains a state (e.g. member variables that change as soon as a pointcut is hit)? Or in other words: is an aspect class a singleton? The source code of the annotation suggests something like this, but I cannot find more details in the documentation.
An example: here is an aspect that counts how often a method has been called. The aspect stores the number of invocations in a map and prints out the map:
@Aspect
public class CountAspect {
private Map<String, Integer> counter = new HashMap<>();
@Before("execution(* *.*(..))")
public void countMethodCalls(JoinPoint jp) {
String methodName = jp.getSignature().getName();
counter.merge(methodName, 1, Integer::sum);
System.out.println(counter);
}
}
When testing this aspect everthing works as expected. When calling methods a, b and c several times, the output is
{main=1}
{a=1, main=1}
{a=1, b=1, main=1}
{a=1, b=1, c=1, main=1}
{a=2, b=1, c=1, main=1}
{a=3, b=1, c=1, main=1}
Is this result reliable? Or does my example only work because I have a rather simple example here?
Could it happen that in a more complex scenario, a second instance of CountAspect would be created by the AspectJ runtime and thus I would lose data collected in the counter map until then?
I am using Load-Time Weaving if that matters.
AspectJ knows multiple instantiation models, one of which (and the default) is singleton. You find more information in the AspectJ manual. There you will see the following instatiation models:
perthis: one aspect instance per caller instance of each matched pointcutpertarget: one aspect instance per callee instance of each matched pointcutpercflow: one aspect instance per entering a certain control flowpercflowbelow: one aspect instance per entering a certain control flow below the intercepted one (everything called by the intercepted method)There is one more instantiation model described here:
pertypewithin: one aspect instance per type (class) as specified by the pointcutSo yes, your aspect as shown in the sample code is a singleton, you can rely on it. Whether you are using compile time weaving, binary weaving or load time weaving does not matter, except maybe if in a container like an application server you deliberately create different weaver instances via class-loader isolation or so.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With