看点发现在运行时执行的所有切入点

问题描述 投票:0回答:1

我需要写一个方面(我们称之为A),显示在运行时所执行的全部切入点。有没有写这样直接指向另外一个切入点,而无需使用方面的姓名电话(...)切入点的方法吗?

我写的东西,大都采用调用泛型函数和()内,这样,当在一个方面,一个函数被调用我的方面的打印出一些东西。我觉得这不是一个理想的解决方案,因为我总是需要写各方面的名称和将长有许多方面。

public class Main {
    public static void main(String[] args) {
        ClassA a = new ClassA();
        a.methodA();
        a.methodA();
        a.methodB();
        a.methodA();
    }
}

public class ClassA {
    public void methodA() {
            System.out.println("MethodA");
    }
    public void methodB() {
        System.out.println("MethodB");
    }
    public void methodC() {
        System.out.println("MethodC");
    }
}

public aspect MethodAAspect {
    pointcut MethA():
        call(public * ClassA.methodA());
    pointcut MethC():
        call(public * ClassA.methodC());
    after():
        MethA() {
            System.out.println("Aspect here, methodA ended.");
        }
    after():
        MethC() {
            System.out.println("Aspect here, methodC ended.");
        }       
}

如果,在这个例子中,我需要的是统计有多少次所有的切入点都被执行,或者当我应该怎么写它执行的切入点打印东西的方面?

java aspectj pointcut
1个回答
2
投票

我不知道我理解正确的话,你想要什么实现的,因为你的描述是有些不精确。例如,一个切入点不是“执行”,施用方法或一个方面内的建议是。所以,我不知道,如果你只想记录每个方法调用(或者方法执行,请参阅下面的差异)或可能需要某种元方面,其对多次建议方面是如何被执行。我在这里假设是前者,更简单的情况下,因为它最有意义给我。

您的应用程序代码,但与包名:

package de.scrum_master.app;

public class ClassA {
  public void methodA() {
    System.out.println("MethodA");
  }

  public void methodB() {
    System.out.println("MethodB");
  }

  public void methodC() {
    System.out.println("MethodC");
  }
}
package de.scrum_master.app;

public class Main {
  public static void main(String[] args) {
    ClassA a = new ClassA();
    a.methodA();
    a.methodA();
    a.methodB();
    a.methodA();
  }
}

看点拦截方法执行:

这方面拦截在自己的代码中的所有方法执行(不来电!)。

package de.scrum_master.aspect;

public aspect MyAspect {
  after() : execution(* *(..)) {
    System.out.println(thisJoinPoint);
  }
}

日志输出是:

MethodA
execution(void de.scrum_master.app.ClassA.methodA())
MethodA
execution(void de.scrum_master.app.ClassA.methodA())
MethodB
execution(void de.scrum_master.app.ClassA.methodB())
MethodA
execution(void de.scrum_master.app.ClassA.methodA())
execution(void de.scrum_master.app.Main.main(String[]))

请注意,也Main.main(..)的执行被记录,即使该方法从未明确地称为(但仍然执行!)。

看点拦截方法执行:

这方面拦截所有的方法,从您自己的代码,其中还包括第三方或JDK类电话通话中。

请注意,为了避免无限循环,我们必须添加&& !within(MyAspect)因为方面的意见还要求JDK的方法。

package de.scrum_master.aspect;

public aspect MyAspect {
  after() : call(* *(..)) && !within(MyAspect) {
    System.out.println(thisJoinPoint);
  }
}

在这种情况下,日志输出是:

MethodA
call(void java.io.PrintStream.println(String))
call(void de.scrum_master.app.ClassA.methodA())
MethodA
call(void java.io.PrintStream.println(String))
call(void de.scrum_master.app.ClassA.methodA())
MethodB
call(void java.io.PrintStream.println(String))
call(void de.scrum_master.app.ClassA.methodB())
MethodA
call(void java.io.PrintStream.println(String))
call(void de.scrum_master.app.ClassA.methodA())

当然,你也可以使用call()和限制调用自己的软件包,例如:

package de.scrum_master.aspect;

public aspect MyAspect {
  after() : call(* de.scrum_master.app..*(..)) && !within(MyAspect) {
    System.out.println(thisJoinPoint);
  }
}

这里的日志输出是:

MethodA
call(void de.scrum_master.app.ClassA.methodA())
MethodA
call(void de.scrum_master.app.ClassA.methodA())
MethodB
call(void de.scrum_master.app.ClassA.methodB())
MethodA
call(void de.scrum_master.app.ClassA.methodA())

它总是取决于你想要达到的目标。

如果这不是你想要的,请更新您的问题更精确,并与评论通知我。然后我看到我能做些什么。


更新其有关元方面跟进的问题:

package de.scrum_master.aspect;

public aspect MetaAspect {
  before() : adviceexecution() && !within(MetaAspect) {
    System.out.println(thisJoinPoint);
  }
}

登录使用MyAspect改变第一execution()版本:

MethodA
adviceexecution(void de.scrum_master.aspect.MyAspect.after(JoinPoint))
execution(void de.scrum_master.app.ClassA.methodA())
MethodA
adviceexecution(void de.scrum_master.aspect.MyAspect.after(JoinPoint))
execution(void de.scrum_master.app.ClassA.methodA())
MethodB
adviceexecution(void de.scrum_master.aspect.MyAspect.after(JoinPoint))
execution(void de.scrum_master.app.ClassA.methodB())
MethodA
adviceexecution(void de.scrum_master.aspect.MyAspect.after(JoinPoint))
execution(void de.scrum_master.app.ClassA.methodA())
adviceexecution(void de.scrum_master.aspect.MyAspect.after(JoinPoint))
execution(void de.scrum_master.app.Main.main(String[]))
© www.soinside.com 2019 - 2024. All rights reserved.