您能通过示例解释AspectJ的cFlow(P& Q)的功能吗?

时间:2015-05-04 20:40:16

标签: java aspectj

我目前正在阅读AspectJ的文档,我对Pointcut composition并不十分了解。特别是,我不明白cFlow(P && Q)做什么,何时执行该切入点的建议。

A PowerPoint presentation(乌得勒支大学的课程)我找到了解释

  

cflow是从参数流出的连接点的集合   切入点。这意味着cflow(P)&& cflow(Q)是交集   两个集合,而cflow(P& Q)意味着你首先结合   切入点P和Q,以及从中流出的所有连接点   在这个系列中。

他们继续列出cFlow(P) && cFlow(Q)pointcut flowPAndflowQ() : cflow(execution(* Example.P(..))) && cflow(execution(* Example.Q(..))) && within(Example);)的所有连接点,对我而言,它看起来像个别语句的所有控制流点的intersection - P∩问:如果你愿意(就像他们说的那样):

  

来自P的流程 - 执行(void Example.P())
  来自P的流程 - 调用(void Example.Q())
  来自P的流程 - 执行(void Example.Q())
  来自Q的流程 - 执行(void Example.Q())
  来自P&&的流量来自Q的流程 - 执行(void Example.Q())

(他们的例子就像AspectJ文档中的那个,除了缺少println()语句。)

我(仍然)不明白,cFlow(P && Q)会做什么。

是否意味着“获取P中的所有连接点,然后添加Q中的所有连接点,然后匹配任何来自其中任何一个的连接点”?如果是这样,我没有得到AspectJ示例的println()语句:System.out.println("should not occur");当然,如果我在P和Q中添加所有流点(即P + Q),那应该是超集(工会)到P∩Q,P ∪ Q

或者它是否意味着“获得P中也是Q的所有连接点”,即  所有流量点都在X()以下?

public void P() { X(); }
public void Q() { X(); }
public void X() { /* all that is in the body of X() */ }

或者它可以永远不会出现,正如AspectJ的例子所述? (为什么?)

如果有人能说清楚,我真的很感激。 :)

1 个答案:

答案 0 :(得分:1)

  

是否意味着"获取P中的所有连接点,然后添加所有连接   在Q中的点,然后匹配从任何流出的任何东西   他们"

不,这意味着获取P和Q中的所有连接点,以便它的交集。

  

或者它是否意味着"获得P中所有也在Q"中的连接点,即   X()下面的所有流点?

是的,"获得P中所有也在Q"剩下的部分没有。原因是切入点P定义了一个连接点:execution(void Example.P()),而切入点Q定义了一个连接点:execution(void Example.Q())。因为这些连接点不同,所以它们的交集是空集。从空集中获取的cflow也是一个空集。这就是为什么在AspectJ文档中这个切入点标有"不应该出现"。

希望这有帮助!

这是Power Point演示文稿的一个误导性引用:

  

cflow(P&& Q)表示您首先将切入点P和Q组合在一起   流出的所有连接点都在此集合中

单词"结合"应替换为" intersect"。

我在Github上创建了一个简单的示例,它复制了PowerPoint演示文稿中的示例:{{3}}

public class Example {
    public void P() {
        Q();
    }

    public void Q() {
    }

    public static void main(String[] args) {
        new Example().P();
    }
}

如果你运行它,输出应该是这样的:

pointcut: P                    join point: execution(Example.P())
pointcut: flowP                join point: execution(Example.P())
pointcut: flowP                join point: call(Example.Q())
pointcut: Q                    join point: execution(Example.Q())
pointcut: flowP                join point: execution(Example.Q())
pointcut: flowQ                join point: execution(Example.Q())
pointcut: flowPAndflowQ        join point: execution(Example.Q())

这表明只有3个连接点:

A: execution(Example.P())
B: call(Example.Q())
C: execution(Example.Q())

切入点:

pointcut P includes only A
pointcut Q includes only C
pointcut flowP includes A, B and C
pointcut flowQ includes only C
pointcut flowPAndflowQ includes only C

我们现在可以看到P&& flow是一个空集,而flowP&& flowQ包括C.

我还包括了额外的切入点:cflow(P()&& publicMethods())(此切入点的建议在代码中被注释掉)。 publicMethods()是执行(public * *(..))。与cflow(P()&& Q())不同,它不会导致空集。