【问题标题】:How can aspectJ pointcuts be used with dynamic selector?aspectJ 切入点如何与动态选择器一起使用?
【发布时间】:2020-07-12 20:53:30
【问题描述】:

我正在开发一个小项目,该项目在测试 Java 应用程序时确定代码覆盖率。它基本上由一个用于 IDE 的插件组成,该插件查找项目中的所有类和方法并将它们保存在数据库中,以及一个带有 aspectJ 切入点的代理,它围绕所有这些方法编织以记录它们的执行。

我的问题是我只想记录由该项目的开发人员实际编写的方法,而不是底层库的方法。所以切入点需要定义为只编织实际项目包中类的方法。另一方面,由于代理要用于各种项目,我无法对这些包进行硬编码。

到目前为止,我的尝试是从数据库中读取所有包名并从中构建一个字符串。基本上它的样子是这样的:

private static final String POINTCUT_STRING = AspectUtil.buildPointcutString();

然后,在定义切入点时:

@Pointcut(POINTCUT_STRING)

问题是,这不起作用,因为显然在定义切入点时,

属性值必须是常量。

那么,我怎样才能使我只能在我的数据库中的包中的类中编织方法?

先谢谢了,祝你好运!

【问题讨论】:

  • 你的MCVE在哪里?

标签: java aop aspectj


【解决方案1】:

我不认为动态方面的方法会起作用,因为 aspectj 不会将编织器暴露给任何状态管理或更改。虽然理论上这在运行时是可能的,但在编译时绝对不可能(并且您可以选择在编译时添加方面)。

但是对于你的问题...

您使用的是什么编织策略?编译还是运行时?我发现 compile 工作得很好,但我不确定如何将 runtime 与 aspectj 一起使用。但我能说的是,如果你使用 compile 无论如何你只会编织应用程序类,因为这就是你可以访问的全部。

另一条评论是,如果你想做一些动态的事情,你最好将条件放在是否监视该方法以获取方面下游的代码覆盖率。所以当切面被执行时,它要做的第一件事就是决定是否应该监控这个类/方法调用的覆盖率,然后从那里继续......

【讨论】:

  • 我明白了。我正在使用运行时编织,但您决定是否进一步监控该方法的观点似乎很有希望。我会尝试一下。谢谢!
  • “运行时编织”是什么意思?加载时编织(LTW)可能吗? IE。您正在使用 aop.xml 吗?我问的是一个特定的原因。
  • @kriegaex 是的,LTW。我正在使用 aop.xml 文件。
  • 我想知道为什么这个答案被接受了。我的解释了 OP 想要什么是可能的。他甚至证实他使用 LTW,我指的是。这个答案更多的是关于CTW。嗯……
【解决方案2】:

当我问你时:

“运行时编织”是什么意思?加载时编织(LTW)可能吗? IE。您正在使用 aop.xml?我问的是一个特定的原因。

你回复了:

是的,LTW。我正在使用 aop.xml 文件。

在这种情况下,您可以选择在 aop.xml 中指定切入点定义,该定义在 JVM 启动期间激活编织代理时读取。如需参考,请阅读 AspectJ 开发人员指南,有一个chapter on LTW。您将在那里找到示例代码和示例 XML 定义,展示了如何使用 XML 文件中的抽象切入点扩展抽象方面并为具体子类指定具体切入点。这应该为您提供将切入点排除在 Java 代码之外所需的选项,无论出于何种原因,您认为这是一件好事并且您需要它。

请注意,您不能期望在运行时修改 aop.xml 并重新加载它,可能会将方面动态地重新应用于所有类。 AspectJ LTW 与类加载一起工作,即在加载所有应用程序类之前,您只有一次 JVM 启动的机会。这不是 AspectJ 的限制,而是 JVM 中字节码检测的工作方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-22
    • 2015-02-10
    相关资源
    最近更新 更多