你能举例说明一下AspectJ的cFlow(P && Q)是干什么的吗?

Can you explain what AspectJ's cFlow(P && Q) does by means of example?

我目前正在浏览 AspectJ 的文档,但我不太明白他们在 Pointcut composition 上的观点。特别是,我不明白 cFlow(P && Q) 的作用,何时会执行带有该切入点的建议。

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

cflow is the collection of join points flowing from the argument pointcut. This means that cflow(P) && cflow(Q) is the intersection of the two collections, while cflow(P && Q) means that you first combine the pointcuts P and Q, and all the join points flowing from that are in this collection.

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

Flow from P - execution(void Example.P())
Flow from P - call(void Example.Q())
Flow from P - execution(void Example.Q())
Flow from Q - execution(void Example.Q())
Flow from P && flow from Q - execution(void Example.Q())

(他们的示例类似于 AspectJ 文档中的示例,只是缺少 println() 语句。)

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

是否意味着"get all join points that are in P, then add all join points that are in Q, then match on anything that flows from any of them"?如果是这样,我没有得到 AspectJ 示例的 println() 语句:System.out.println("should not occur"); 当然,如果我在 P 和 Q 中添加所有流点(即 P + Q),那应该是超集(并集)到P∩Q,P ∪ Q?

或者它的意思是"get all join points in P that are also in Q",即 以下 X() 内的所有流量点?

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

或者它永远不会发生,就像 AspectJ 的例子所说的那样? (为什么?)

如果有人能阐明一些问题,我将不胜感激。 :)

Does it mean "get all join points that are in P, then add all join points that are in Q, then match on anything that flows from any of them"?

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

Or does it mean "get all join points in P that are also in Q", i.e. all flow points within X() below?

"get all join points in P that are also in Q" 是,其余部分否。原因是切入点 P 定义了一个单一的连接点:execution(void Example.P()),而切入点 Q 定义了一个单一的连接点:execution(void Example.Q())。因为这些连接点不同,所以它们的交集是一个空集。取自空集的 cflow 也是一个空集。这就是为什么在 AspectJ 文档中这个切入点用 "should not occur".

标记的原因

希望对您有所帮助!

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

cflow(P && Q) means that you first combine the pointcuts P and Q, and all the join points flowing from that are in this collection

单词"combine"应替换为"intersect"。

我在 Github 上创建了一个简单示例,它复制了 PowerPoint 演示文稿中的示例:https://github.com/medvedev1088/aspectj-cflow-composition-example

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 && Q是一个空集,而flowP && flowQ包含了C。

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