在正常定义Aspect时,每个Aspect的实例仅对应于一个Spring容器(ApplicationContext),也就是,Aspect跟其他对象一样,在Spring容器中默认以单例的形式存在,不过AspectJ语法可以通过提供注解值来改变这种默认模式。
Spring AOP支持perthis和pertarget,perthis代表针对切点的所在的代理对象是一对一的,pertarget代表针对切点所在的目标对象是一对一的。这样假设businessService过滤出了两个符合条件的类,比如过滤出了MyService1和MyService2,那么对应这两个类的实例就会对应不同的MyAspect的实例,如果不添加perthis,默认情况是这两个类的实例对应的是同一个MyAspect的实例。
@Aspect("perthis(com.xyz.myapp.SystemArchitecture.businessService())")
public class MyAspect {
private int someState;
@Before(com.xyz.myapp.SystemArchitecture.businessService())
public void recordServiceUsage() {
// ...
}
}
个人认为,这种高级用法大多数情况下应该是不需要用到的,毕竟把状态存储在Aspect中(以原型来保证线程安全),我本人还想不到什么场景会使用到。