面向方面的编程 - 什么是“cflow”?

发布于 2024-10-20 11:49:32 字数 314 浏览 1 评论 0原文

我已经提到了 AspectJ 参考这里它指出' cflow' 是

cflow(Pointcut) - 中的每个连接点 每个连接点P的控制流程 通过Pointcut挑选出来,包括P 本身

并不完全清楚,我想知道是否有人可以详细说明 cflow 的含义?为什么要使用它?

确实谢谢。

I have referred to the AspectJ reference here it states that the 'cflow' is

cflow(Pointcut) - every join point in
the control flow of each join point P
picked out by Pointcut, including P
itself

This isn't entirely lucid for me and I was wondering if someone could elaborate a little more on the meaning of cflow please? Why use it?

Thanks indeed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清风疏影 2024-10-27 11:49:32

cflow 可帮助您为整个控制流程提供建议。让我们尝试一个例子,我有 4 个小类

public class A {

    public static void methodA() {
        B.methodB();
    }

}

public class B {

    public static void methodB() {
        C.methodC();
        int a = 1;
        int b = 2;
        System.out.println( a + b );
    }

}

public class C {

    public static void methodC() {
        D.methodD();
    }

}

public class D {

    public static void methodD() {

    }

}

,我的方面:

public aspect CFlow {

    public pointcut flow() : cflow(call( * B.methodB() ) ) && !within(CFlow);

    before() : flow() {
        System.out.println( thisJoinPoint );
    }

}

和我的跑步者(只是为了看看会发生什么):

public class Test {

    public static void main(String[] args) {
        A.methodA();
    }

}

在我的切入点中,你可以看到 cflow(call( * B.methodB() ) ),所以我想从 B.methodB 调用开始切面控制流,当您运行 Test 类时,您会在控制台上看到:

call(void test.B.methodB())
staticinitialization(test.B.<clinit>)
execution(void test.B.methodB())
call(void test.C.methodC())
staticinitialization(test.C.<clinit>)
execution(void test.C.methodC())
call(void test.D.methodD())
staticinitialization(test.D.<clinit>)
execution(void test.D.methodD())
get(PrintStream java.lang.System.out)
call(void java.io.PrintStream.println(int))
3

最后一个字符串不属于切面,这只是因为 System. methodB 内的 out.println。所有打印的内容都显示您控制流程 - 方法链和“事件”(执行、调用、初始化...)。你看,我从 Test 类开始,它调用 methodA 但它们不在“堆栈”中,因为我们对 methodB 控制流感兴趣。

如果您想获取该堆栈,但没有第一行(调用自身),您可以尝试定义

public pointcut flow() :  cflowbelow(call( * B.methodB() ) ) && !within(CFlow);

cflowbelow 是另一个切入点,这意味着控制流不包括指定的(在我们的例子中调用 B.methodB)。

小心在切入点中添加 !within(_aspect_) ,否则你除了 StackOverflowError 之外什么也得不到。发生这种情况是因为 cflow 无法在编译时定义,而在运行时方面也属于控制流(因此它导致永恒递归......)

好吧,将控制流视为类似于调用堆栈,然后你会得到一个它的用法的想法;)

cflow helps you to advice the whole control flow. Let's try an example, I have 4 small classes

public class A {

    public static void methodA() {
        B.methodB();
    }

}

public class B {

    public static void methodB() {
        C.methodC();
        int a = 1;
        int b = 2;
        System.out.println( a + b );
    }

}

public class C {

    public static void methodC() {
        D.methodD();
    }

}

public class D {

    public static void methodD() {

    }

}

my aspect:

public aspect CFlow {

    public pointcut flow() : cflow(call( * B.methodB() ) ) && !within(CFlow);

    before() : flow() {
        System.out.println( thisJoinPoint );
    }

}

and my runner (just to see what happens):

public class Test {

    public static void main(String[] args) {
        A.methodA();
    }

}

in my pointcut you could see cflow(call( * B.methodB() ) ), so I want to aspect control flow starting from B.methodB calling, and when you run Test class you see on console:

call(void test.B.methodB())
staticinitialization(test.B.<clinit>)
execution(void test.B.methodB())
call(void test.C.methodC())
staticinitialization(test.C.<clinit>)
execution(void test.C.methodC())
call(void test.D.methodD())
staticinitialization(test.D.<clinit>)
execution(void test.D.methodD())
get(PrintStream java.lang.System.out)
call(void java.io.PrintStream.println(int))
3

last string does not belong to aspect, it is just because of System.out.println inside methodB. All printed shows you control flow - chains of methods and 'events' (execution, calling, initializations...). You see, I started from Test class, which called methodA but they are not in 'stack', because we were interested in methodB control flow.

If you want to get that stack, but without first line (calling itself), you could try to define

public pointcut flow() :  cflowbelow(call( * B.methodB() ) ) && !within(CFlow);

cflowbelow is another pointcut, which means control flow excluding specified (in our case calling B.methodB).

Be careful to add !within(_aspect_) in pointcut, otherwise you will get nothing good but StackOverflowError. It happens because cflow can't be defined at compile time, and at runtime aspect belongs to control flow too (so it leads to eternal recursion...)

well, think of control flow as similar to call stack, then you will get an idea of its usage ;)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文