When creating aspects using the Aspect annotation as described here , is it possible to use this annotation with a class that contains a state (eg 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 pointcut pertarget
: one aspect instance per callee instance of each matched pointcut percflow
: one aspect instance per entering a certain control flow percflowbelow
: 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 pointcut So 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.