切面实例化模型
这是一个高级主题。如果你刚开始接触 AOP,可以安全地跳过本部分,稍后再学习。 |
默认情况下,应用上下文中的每个切面只有一个实例。AspectJ 将此称为单例实例化模型。可以定义具有其他生命周期的切面。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
的每个唯一对象)创建一个切面实例。切面实例在服务对象上的方法首次被调用时创建。当服务对象超出作用域时,切面也超出作用域。在切面实例创建之前,其中没有任何通知会运行。一旦切面实例创建,其中声明的通知就会在匹配的连接点处运行,但仅当服务对象是与该切面关联的对象时。有关 per
子句的更多信息,请参阅 AspectJ 编程指南。
pertarget
实例化模型的工作方式与 perthis
完全相同,但它在匹配的连接点处为每个唯一的目标对象创建一个切面实例。