我正在研究一个小型项目,该项目在测试Java应用程序时确定代码覆盖率。它基本上包括一个用于IDE的插件,该插件可找到项目中的所有类和方法并将其保存在数据库中;以及一个具有AspectJ切入点的代理,这些切入点编织了所有这些方法以记录其执行。
我遇到的问题是,我只想记录该项目的开发人员实际写的方法,而不记录基础库的方法。因此,切入点需要以仅编织实际项目包中的类方法的方式进行定义。另一方面,由于该代理将用于各种项目,所以我无法对这些软件包进行硬编码。
到目前为止,我的尝试是从数据库中读取所有软件包名称,并从中构建一个字符串。基本上是这样的:
return Observable.defer(() => {
const params = new HttpParams()
.set('username', 'swapp')
.set('password', "test");
return this.http
.get('myurl', {params: params})
.subscribe(this.onsuccessHandler,this.errorHandler);
.finally(() => {}
);
然后,在定义切入点时:
private static final String POINTCUT_STRING = AspectUtil.buildPointcutString();
事实是,这不起作用,因为显然在定义切入点时,
属性值必须为常数。
那么,如何做到这一点,使我只能在数据库中包含的包中的类中编织方法?
预先感谢,祝您愉快!
答案 0 :(得分:2)
我不认为动态方面方法会起作用,因为Aspectj不会使编织者面临任何状态管理或更改。尽管从理论上讲这在运行时是可行的,但在编译时绝对是不可能的(并且您可以选择在编译时添加方面)。
但是对于您的问题...
您正在使用哪种编织策略?编译还是运行时?我发现编译可以很好地工作,而且我不确定如何在Aspectj中使用运行时。但是我能说的是,如果您使用编译,则无论如何都只能编织应用程序类,因为那是您将有权访问的全部。
要发表的另一条评论是,如果您想做一些动态的事情,最好把条件放在是否要监视方面的下游代码覆盖率的方法上。因此,当执行方面时,首先要做的是确定是否应监视此类/方法调用的覆盖范围,然后从那里继续进行...
答案 1 :(得分:2)
当我问你:
“运行时编织”是什么意思?加载时间编织(LTW)也许吗?即您正在使用 aop.xml 吗?我是出于特定原因。
您回答:
是的,LTW。我正在使用 aop.xml 文件。
在这种情况下,您可以选择在 aop.xml 中指定切入点定义,该激活在编织代理激活时在JVM启动期间读取。有关参考,请阅读AspectJ开发人员指南,其中有一个chapter on LTW。您将在此处找到样本代码和样本XML定义,展示了如何在XML文件中使用抽象切入点扩展抽象方面并为具体子类指定具体切入点。不管出于什么原因,您都认为这是一件好事,而且您需要它,这应该为您提供了使切入点保持在Java代码之外所需的选项。
请注意,您不能期望在运行时期间修改 aop.xml 并重新加载它,可能会将该方面动态地重新应用于所有类。 AspectJ LTW与类加载一起工作,即在加载所有应用程序类之前,您只有一次在JVM启动时尝试一下。这不是AspectJ的限制,而是JVM中字节码检测的工作方式。