AspectJ 方面是单例吗?
Are AspectJ aspects Singletons?
使用 Aspect annotation as described here 创建方面时,是否可以将此注释与包含状态的 class 一起使用(例如,一旦命中切入点就会更改的成员变量)?或者换句话说:方面 class 是单例吗?注释的源代码建议类似这样,但我无法在文档中找到更多详细信息。
举个例子:这是一个计算方法被调用频率的方面。方面将调用次数存储在映射中并打印出映射:
@Aspect
public class CountAspect {
private Map<String, Integer> counter = new HashMap<>();
@Before("execution(* *.*(..))")
public void countMethodCalls(JoinPoint jp) {
String methodName = jp.getSignature().getName();
counter.merge(methodName, 1, Integer::sum);
System.out.println(counter);
}
}
测试这方面时,一切都按预期工作。多次调用方法a
、b
和c
时,输出为
{main=1}
{a=1, main=1}
{a=1, b=1, main=1}
{a=1, b=1, c=1, main=1}
{a=2, b=1, c=1, main=1}
{a=3, b=1, c=1, main=1}
这个结果靠谱吗?还是我的示例只起作用,因为我这里有一个相当简单的示例?
在更复杂的情况下,AspectJ 运行时会创建 CountAspect
的第二个实例,因此我会丢失在 counter
地图中收集的数据吗?
如果重要的话,我正在使用加载时编织。
AspectJ 知道多种实例化模型,其中之一(默认)是单例。您可以在 AspectJ manual 中找到更多信息。在那里您将看到以下安装模型:
perthis
:每个匹配切入点调用者实例一个方面实例
pertarget
:每个匹配切入点被调用者实例的一个方面实例
percflow
:每进入某个控制流一个方面实例
percflowbelow
:每进入一个方面实例一个特定的控制流低于被拦截的(被拦截的方法调用的一切)
描述了另一种实例化模型here:
pertypewithin
:切入点 指定的每个类型(class)一个方面实例
所以是的,示例代码中显示的方面是单例,您可以依赖它。无论您使用的是编译时织入、二进制织入还是加载时织入都无关紧要,除非您在像应用程序服务器这样的容器中通过 class-loader 隔离等方式故意创建不同的织入器实例。
使用 Aspect annotation as described here 创建方面时,是否可以将此注释与包含状态的 class 一起使用(例如,一旦命中切入点就会更改的成员变量)?或者换句话说:方面 class 是单例吗?注释的源代码建议类似这样,但我无法在文档中找到更多详细信息。
举个例子:这是一个计算方法被调用频率的方面。方面将调用次数存储在映射中并打印出映射:
@Aspect
public class CountAspect {
private Map<String, Integer> counter = new HashMap<>();
@Before("execution(* *.*(..))")
public void countMethodCalls(JoinPoint jp) {
String methodName = jp.getSignature().getName();
counter.merge(methodName, 1, Integer::sum);
System.out.println(counter);
}
}
测试这方面时,一切都按预期工作。多次调用方法a
、b
和c
时,输出为
{main=1}
{a=1, main=1}
{a=1, b=1, main=1}
{a=1, b=1, c=1, main=1}
{a=2, b=1, c=1, main=1}
{a=3, b=1, c=1, main=1}
这个结果靠谱吗?还是我的示例只起作用,因为我这里有一个相当简单的示例?
在更复杂的情况下,AspectJ 运行时会创建 CountAspect
的第二个实例,因此我会丢失在 counter
地图中收集的数据吗?
如果重要的话,我正在使用加载时编织。
AspectJ 知道多种实例化模型,其中之一(默认)是单例。您可以在 AspectJ manual 中找到更多信息。在那里您将看到以下安装模型:
perthis
:每个匹配切入点调用者实例一个方面实例pertarget
:每个匹配切入点被调用者实例的一个方面实例percflow
:每进入某个控制流一个方面实例percflowbelow
:每进入一个方面实例一个特定的控制流低于被拦截的(被拦截的方法调用的一切)
描述了另一种实例化模型here:
pertypewithin
:切入点 指定的每个类型(class)一个方面实例
所以是的,示例代码中显示的方面是单例,您可以依赖它。无论您使用的是编译时织入、二进制织入还是加载时织入都无关紧要,除非您在像应用程序服务器这样的容器中通过 class-loader 隔离等方式故意创建不同的织入器实例。