Hands-On High Performance with Spring 5
上QQ阅读APP看书,第一时间看更新

Aspect instantiation models

By default, the declared aspect is singleton, so there will be only one instance of our aspect per class loader (and not per JVM). The instance of our aspect will be destroyed only when the class loader is garbage.

If we need to have our aspect with private attributes hold data relative to class instances, the aspect needs to be stateful. To do so, Spring with its AspectJ support provides a way using perthis and pertarget instantiation models. AspectJ is an independent library, and has other instantiation models in addition to perthis and pertarget, such as percflow, percflowbelowand pertypewithin, which are not supported in Spring's AspectJ support.

To create a stateful aspect using perthis, we need to declare perthis as follows in our @Aspect declaration:

@Aspect("perthis(com.packt.springhighperformance.ch03.bankingapp.service.TransferService.transfer())")
public class TransferAspect {
//Add your per instance attributes holding private data
//Define your advice methods
}

Once we declare our @Aspect with the perthis clause, one aspect instance will be created for each unique TransferService object executing the transfer method (each unique object that is bound to this at join points matched by the pointcut expression). The instance of aspect goes out of scope when the TransferService object goes out of scope.

pertarget works the same as perthis; however, in pertarget, it creates one aspect instance per unique target object at join points matched by the pointcut expression.

Now you might be wondering how Spring would have applied advice without making calls from the business logic classes to the crosscutting concern class (Aspects). So the answer is, Spring does this using the proxy pattern. It weaves your Aspects to the target objects by creating proxied objects. Let's look at the Spring AOP proxy in detail in the next section.