简体   繁体   中英

Are AspectJ aspects Singletons?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM