方面实例化模型(Aspect Instantiation Models)
备注
这是一个高级主题。如果你刚开始接触AOP(面向切面编程),可以暂时跳过这一部分,等到以后再学习。
默认情况下,应用程序上下文中每个切面(aspect)都只有一个实例。AspectJ将这种模型称为“单例实例化模型”(singleton instantiation model)。也可以定义具有其他生命周期的切面。Spring支持AspectJ的perthis、pertarget和pertypewithin实例化模型;而percflow和percflowbelow目前尚不受支持。
你可以通过在@Aspect注解中指定perthis子句来声明一个perthis切面。请考虑以下示例:
- Java
- Kotlin
@Aspect("perthis(execution(* com.xyz..service.*.*(..)))")
public class MyAspect {
private int someState;
@Before("execution(* com.xyz..service.*.*(..))")
public void recordServiceUsage() {
// ...
}
}
@Aspect("perthis(execution(* com.xyz..service.*.*(..)))")
class MyAspect {
private val someState: Int = 0
@Before("execution(* com.xyz..service.*.*(..))")
fun recordServiceUsage() {
// ...
}
}
在前面的例子中,perthis 子句的效果是:对于每个执行业务服务的唯一服务对象(即在由切入点表达式匹配的连接点处与 this 绑定的每个唯一对象),都会创建一个切面实例。当第一次在服务对象上调用方法时,才会创建该切面实例。当服务对象超出作用域时,切面实例也会随之超出作用域。在切面实例被创建之前,其中的任何 advised 代码都不会执行。一旦切面实例被创建,其中声明的 advised 代码就会在匹配的连接点处执行,但前提是执行该代码的服务对象必须是与该切面关联的服务对象本身。有关 perthis 子句的更多信息,请参阅《AspectJ 编程指南》。
pertarget实例化模型的工作方式与perthis完全相同,但它会在匹配的连接点(join points)为每个唯一的目标对象创建一个方面(aspect)实例。