:::info 这是一个高级话题。如果你刚开始接触 AOP,你可以安全地跳过它,直到以后再来观看 :::
默认情况下,每个切面(aspect)在应用上下文中都有一个实例。AspectJ 把这称为单实例模型。我们可以用其他的生命周期来定义切面。Spring 支持 AspectJ 的 perthis 和 pertarget 实例化模型;目前不支持 percflow、percflowbelow 和 pertypewithin。
你可以通过在 @Aspect 注解中指定一个 perthis 子句来声明一个 perthis 切面。请看下面的例子:
@Aspect("perthis(com.xyz.myapp.CommonPointcuts.businessService())")
public class MyAspect {
private int someState;
@Before("com.xyz.myapp.CommonPointcuts.businessService()")
public void recordServiceUsage() {
// ...
}
}
在前面的例子中,perthis 子句的作用是为执行业务服务的每个独特的服务对象(在由 pointcut 表达式匹配的连接点上绑定到此的每个独特对象)创建一个切面实例。当服务对象上的方法第一次被调用时,该切面实例被创建。当服务对象超出范围时,该切面就超出了范围。在切面实例被创建之前,它里面的任何 advice 都不会运行。一旦切面实例被创建,其中声明的 advice 就会在匹配的连接点上运行,但只有当服务对象是与该切面相关联的对象时才会运行。关于 per 条款的更多信息,请参见《AspectJ 编程指南》。
pertarget 实例化模型的工作方式与 perthis 完全相同,但它在匹配的连接点上为每个独特的目标对象创建一个切面实例。
:::tips 确实是高级的,介绍都只有寥寥的提到了一句 :::