aspectJ 切入点如何与动态选择器一起使用?
How can aspectJ pointcuts be used with dynamic selector?
我正在做一个小项目,该项目在测试 java 应用程序时确定代码覆盖率。它基本上包含一个 IDE 的插件,它可以找到项目中的所有 类 和方法,并将它们保存在数据库中,以及一个带有 aspectJ 切入点的代理,它围绕所有这些方法来记录它们执行。
我遇到的问题是我只想记录该项目的开发人员实际编写的方法,而不是底层库的方法。所以切入点的定义方式需要只织入实际项目包中类的方法。另一方面,由于代理要与各种项目一起使用,我不能对这些包进行硬编码。
到目前为止,我的尝试是从数据库中读取所有包名称并从中构建一个字符串。基本上它看起来像这样:
private static final String POINTCUT_STRING = AspectUtil.buildPointcutString();
然后,在定义切入点时:
@Pointcut(POINTCUT_STRING)
事实是,这不起作用,因为显然在定义切入点时,
Attribute value needs to be a constant.
那么,我怎样才能做到只能在我的数据库中的包中 类 编织方法?
在此先感谢,祝您玩得愉快!
我认为动态方面方法不会奏效,因为 aspectj 不会将编织器暴露给任何状态管理或更改。尽管这在理论上在运行时是可能的,但在编译时绝对不可能(并且您可以选择在编译时添加方面)。
但是对于你的问题...
您使用什么编织策略?编译还是运行时?我发现编译工作得很好,但我不确定如何将运行时与 aspectj 一起使用。但我可以说的是,如果你使用编译,你只会编织应用程序 类 在任何情况下,因为这是你可以访问的所有内容。
另一条评论是,如果您想做一些动态的事情,您最好将条件放在是否监视该方法的下游方面的代码覆盖率上。因此,当执行方面时,它要做的第一件事是决定是否应监视此 class/method 调用的覆盖范围,然后从那里继续...
当我问你的时候:
What do you mean by "runtime weaving"? Load-time weaving (LTW) maybe? I.e. you are using aop.xml? I am asking for a specific reason.
您回复了:
Yes, LTW. I am using an aop.xml file.
在这种情况下,您可以选择在 aop.xml 中指定切入点定义,当编织代理被激活时,它会在 JVM 启动期间读取。如需参考,请阅读 AspectJ 开发人员指南,其中有一个 chapter on LTW。您会在那里找到示例代码和示例 XML 定义,展示如何在 XML 文件中使用抽象切入点扩展抽象方面,并为具体子 class 指定具体切入点。这应该为您提供将切入点保留在 Java 代码之外所需的选项,无论出于何种原因您认为这是一件好事并且您需要它。
请注意,您不能指望在运行时修改 aop.xml 并重新加载它,可能会将方面动态地重新应用到所有 class es。 AspectJ LTW 与 class 加载一起工作,即在加载所有应用程序 class 之前,您只有一次 JVM 启动机会。这不是 AspectJ 的限制,而是 JVM 中字节码检测的工作方式。
我正在做一个小项目,该项目在测试 java 应用程序时确定代码覆盖率。它基本上包含一个 IDE 的插件,它可以找到项目中的所有 类 和方法,并将它们保存在数据库中,以及一个带有 aspectJ 切入点的代理,它围绕所有这些方法来记录它们执行。
我遇到的问题是我只想记录该项目的开发人员实际编写的方法,而不是底层库的方法。所以切入点的定义方式需要只织入实际项目包中类的方法。另一方面,由于代理要与各种项目一起使用,我不能对这些包进行硬编码。
到目前为止,我的尝试是从数据库中读取所有包名称并从中构建一个字符串。基本上它看起来像这样:
private static final String POINTCUT_STRING = AspectUtil.buildPointcutString();
然后,在定义切入点时:
@Pointcut(POINTCUT_STRING)
事实是,这不起作用,因为显然在定义切入点时,
Attribute value needs to be a constant.
那么,我怎样才能做到只能在我的数据库中的包中 类 编织方法?
在此先感谢,祝您玩得愉快!
我认为动态方面方法不会奏效,因为 aspectj 不会将编织器暴露给任何状态管理或更改。尽管这在理论上在运行时是可能的,但在编译时绝对不可能(并且您可以选择在编译时添加方面)。
但是对于你的问题...
您使用什么编织策略?编译还是运行时?我发现编译工作得很好,但我不确定如何将运行时与 aspectj 一起使用。但我可以说的是,如果你使用编译,你只会编织应用程序 类 在任何情况下,因为这是你可以访问的所有内容。
另一条评论是,如果您想做一些动态的事情,您最好将条件放在是否监视该方法的下游方面的代码覆盖率上。因此,当执行方面时,它要做的第一件事是决定是否应监视此 class/method 调用的覆盖范围,然后从那里继续...
当我问你的时候:
What do you mean by "runtime weaving"? Load-time weaving (LTW) maybe? I.e. you are using aop.xml? I am asking for a specific reason.
您回复了:
Yes, LTW. I am using an aop.xml file.
在这种情况下,您可以选择在 aop.xml 中指定切入点定义,当编织代理被激活时,它会在 JVM 启动期间读取。如需参考,请阅读 AspectJ 开发人员指南,其中有一个 chapter on LTW。您会在那里找到示例代码和示例 XML 定义,展示如何在 XML 文件中使用抽象切入点扩展抽象方面,并为具体子 class 指定具体切入点。这应该为您提供将切入点保留在 Java 代码之外所需的选项,无论出于何种原因您认为这是一件好事并且您需要它。
请注意,您不能指望在运行时修改 aop.xml 并重新加载它,可能会将方面动态地重新应用到所有 class es。 AspectJ LTW 与 class 加载一起工作,即在加载所有应用程序 class 之前,您只有一次 JVM 启动机会。这不是 AspectJ 的限制,而是 JVM 中字节码检测的工作方式。