我目前正在阅读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的例子所述? (为什么?)
如果有人能说清楚,我真的很感激。 :)
答案 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())不同,它不会导致空集。