简体   繁体   English

AspectJ 方面是单例吗?

[英]Are AspectJ aspects Singletons?

When creating aspects using the Aspect annotation as described here , is it possible to use this annotation with a class that contains a state (eg member variables that change as soon as a pointcut is hit)?当使用这里描述的Aspect 注释创建方面时,是否可以将此注释与包含状态的类一起使用(例如,一旦点击切入点就会更改成员变量)? Or in other words: is an aspect class a singleton?或者换句话说:方面类是单例吗? The source code of the annotation suggests something like this, but I cannot find more details in the documentation.注释的源代码提出了类似的建议,但我在文档中找不到更多详细信息。

An example: here is an aspect that counts how often a method has been called.一个例子:这是一个计算方法被调用频率的方面。 The aspect stores the number of invocations in a map and prints out the map:方面将调用次数存储在地图中并打印出地图:

@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);
    }
}

When testing this aspect everthing works as expected.在测试这方面时,一切都按预期工作。 When calling methods a , b and c several times, the output is多次调用abc方法时,输出为

{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}

Is this result reliable?这个结果可靠吗? Or does my example only work because I have a rather simple example here?或者我的示例是否仅有效,因为我这里有一个相当简单的示例?

Could it happen that in a more complex scenario, a second instance of CountAspect would be created by the AspectJ runtime and thus I would lose data collected in the counter map until then?在更复杂的场景中,AspectJ 运行时会创建CountAspect的第二个实例,因此在此之前我会丢失counter映射中收集的数据吗?

I am using Load-Time Weaving if that matters.如果重要的话,我正在使用加载时编织。

AspectJ knows multiple instantiation models, one of which (and the default) is singleton. AspectJ 知道多个实例化模型,其中之一(也是默认的)是单例模型。 You find more information in the AspectJ manual .您可以在AspectJ 手册中找到更多信息。 There you will see the following instatiation models:在那里您将看到以下安装模型:

  • perthis : one aspect instance per caller instance of each matched pointcut perthis : 每个匹配切入点的每个调用者实例一个方面实例
  • pertarget : one aspect instance per callee instance of each matched pointcut pertarget : 每个匹配切入点的每个被调用者实例一个方面实例
  • percflow : one aspect instance per entering a certain control flow percflow : 每个进入某个控制流的一个方面实例
  • percflowbelow : one aspect instance per entering a certain control flow below the intercepted one (everything called by the intercepted method) percflowbelow :每进入一个低于被拦截的控制流的特定控制流的一个方面实例(被拦截的方法调用的所有东西)

There is one more instantiation model described here :这里描述另一种实例化模型:

  • pertypewithin : one aspect instance per type (class) as specified by the pointcut pertypewithin :切入点指定的每个类型(类)的一个方面实例

So yes, your aspect as shown in the sample code is a singleton, you can rely on it.所以是的,示例代码中显示的方面是单例,您可以依赖它。 Whether you are using compile time weaving, binary weaving or load time weaving does not matter, except maybe if in a container like an application server you deliberately create different weaver instances via class-loader isolation or so.无论您是使用编译时编织、二进制编织还是加载时编织都没有关系,除非在应用服务器等容器中您有意通过类加载器隔离等方式创建不同的编织器实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM