Java 方面来查找运行时执行的所有切入点
我需要编写一个方面(让我们称之为A)来显示运行时执行的所有切入点。有没有一种方法可以编写一个类似切入点的调用(…),直接指向另一个切入点,而不使用方面的名称 我写了一些东西,主要使用泛型函数和in()的调用,这样当一个方面中的函数被称为my aspect时,a就会打印一些东西。我觉得这不是一个理想的解决方案,因为我总是需要写下所有方面的名称,而且很多方面都很长Java 方面来查找运行时执行的所有切入点,java,aspectj,pointcut,Java,Aspectj,Pointcut,我需要编写一个方面(让我们称之为A)来显示运行时执行的所有切入点。有没有一种方法可以编写一个类似切入点的调用(…),直接指向另一个切入点,而不使用方面的名称 我写了一些东西,主要使用泛型函数和in()的调用,这样当一个方面中的函数被称为my aspect时,a就会打印一些东西。我觉得这不是一个理想的解决方案,因为我总是需要写下所有方面的名称,而且很多方面都很长 public class Main { public static void main(String[] args) {
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.");
}
}
在本例中,如果我需要一个方面来计算所有切入点执行了多少次,或者在执行切入点时打印了一些东西,我应该如何编写它?我不确定我是否正确理解了您想要实现的目标,因为您的描述有点不精确。例如,切入点不是“执行的”,应用程序方法或方面内的建议是“执行的”。因此,我不确定您是否只想记录每个方法调用(或者可能是方法执行,请参见下面的区别),或者可能需要某种元方面,计算方面建议执行的次数。我在这里假设前一个更简单的例子,因为它对我来说最有意义 您的应用程序代码,但包含程序包名称:
package de.scrum\u master.app;
甲级公共课{
公开无效方法a(){
System.out.println(“MethodA”);
}
公共无效方法b(){
System.out.println(“方法B”);
}
公共无效方法c(){
System.out.println(“MethodC”);
}
}
package de.scrum\u master.app;
公共班机{
公共静态void main(字符串[]args){
ClassA=新ClassA();
a、 方法a();
a、 方法a();
a、 方法b();
a、 方法a();
}
}
方面拦截方法执行:
此特性拦截您自己代码中的所有方法执行(而不是调用!)
package de.scrum\u master.aspect;
公共方面我的方面{
after():执行(**(..){
System.out.println(此连接点);
}
}
日志输出为:
MethodA
执行(void de.scrum_master.app.ClassA.methodA())
方法
执行(void de.scrum_master.app.ClassA.methodA())
方法B
执行(void de.scrum_master.app.ClassA.methodB())
方法
执行(void de.scrum_master.app.ClassA.methodA())
执行(void de.scrum_master.app.Main.Main(String[]))
请注意,Main.Main(…)
的执行也被记录下来,即使该方法从未被显式调用(但仍然执行!)
方面拦截方法执行:
此特性截取来自您自己代码的所有方法调用,其中还包括对第三方或JDK类的调用
请注意,为了避免无休止的循环,我们必须添加&&!在(MyAspect)
中,因为aspect通知还调用JDK方法
package de.scrum\u master.aspect;
公共方面我的方面{
after():在(MyAspect)中调用(**(..)&&&{
System.out.println(此连接点);
}
}
本例中的日志输出为:
MethodA
调用(void java.io.PrintStream.println(字符串))
调用(void de.scrum\u master.app.ClassA.methodA())
方法
调用(void java.io.PrintStream.println(字符串))
调用(void de.scrum\u master.app.ClassA.methodA())
方法B
调用(void java.io.PrintStream.println(字符串))
调用(void de.scrum\u master.app.ClassA.methodB())
方法
调用(void java.io.PrintStream.println(字符串))
调用(void de.scrum\u master.app.ClassA.methodA())
当然,您也可以使用call()
并将调用限制在您自己的包中,例如:
package de.scrum\u master.aspect;
公共方面我的方面{
after():在(MyAspect)中调用(*de.scrum_master.app.*(..)&&&&{
System.out.println(此连接点);
}
}
此处的日志输出为:
MethodA
调用(void de.scrum\u master.app.ClassA.methodA())
方法
调用(void de.scrum\u master.app.ClassA.methodA())
方法B
调用(void de.scrum\u master.app.ClassA.methodB())
方法
调用(void de.scrum\u master.app.ClassA.methodA())
它总是取决于你想要实现什么
如果这不是你想要的,请更新你的问题更准确,并通知我一个评论。然后我看看我能做什么
关于元方面后续问题的更新:
package de.scrum\u master.aspect;
公共方面元方面{
before():adviceexecution()&&!在(MetaAspect)内{
System.out.println(此连接点);
}
}
使用execution()
更改来记录第一个MyAspect
版本:
MethodA
adviceexecution(void de.scrum_master.aspect.MyAspect.after(连接点))
执行(void de.scrum_master.app.ClassA.methodA())
方法
adviceexecution(void de.scrum_master.aspect.MyAspect.after(连接点))
执行(void de.scrum_master.app.ClassA.methodA())
方法B
adviceexecution(void de.scrum_master.aspect.MyAspect.after(连接点))
执行(void de.scrum_master.app.ClassA.methodB())
方法
adviceexecution(void de.scrum_master.aspect.MyAspect.after(连接点))
执行(void de.scrum_master.app.ClassA.methodA())
adviceexecution(void de.scrum_master.aspect.MyAspect.after(连接点))
执行(void de.scrum_master.app.Main.Main(String[]))
我不确定我是否正确理解了您想要实现的目标,因为您的描述有点不准确。例如,切入点不是“执行的”,应用程序方法或方面内的建议是“执行的”。因此,我不确定您是否只想记录每个方法调用(或者可能是方法执行,请参见下面的区别),或者可能需要某种元方面,计算方面建议执行的次数。我在这里假设前一个更简单的例子,因为它对我来说最有意义
您的应用程序代码,但包含程序包名称:
包