我想验证代码是否由AspectJ编写。我听说过的一种方法是使用字节伙伴库中的代理。不幸的是,我完全是绿色的,我不知道该怎么办。
我尝试将JADE与代理一起使用,但是字节伙伴对我自己更友好,我认为它更合适。
为了验证该方法,我创建了一个带有MySQL连接的简单springboot应用程序,并添加了一些AspectJ代码。我尝试使用Spring AOP,但是AOP无法读取私有方法,因此我决定将我的想法与AspectJ一起提供。
我已经使用了另一个方面来定义joinPoints并引发异常,但是这很困难并且需要很多工作并且结果很低。
您对使用字节伙伴检测AspectJ的代理的方法或实现有任何想法吗?
最佳答案
首先回答您的评论:
我想对不可信的代码有更多的经验。例如,如果我用Java开发了一个大型项目,然后得到了一些由AspectJ创建的更改的不受信任的插件,那么我更愿意知道该怎么做才能检查我的类是否受AspectJ的保护或AspectJ只是编织到我的类中。
对于AspectJ,有两种情况:
编译时编织
您的应用程序不使用AspectJ,在Maven构建中不使用AspectJ Maven插件,也不在Gradle构建中使用类似的东西:即使您的第三方库位于类路径中,也没有任何东西编入您自己的代码中。怎么可能没有AspectJ编译器。
您的应用程序使用AspectJ编译器:即使第三方库位于类路径中,也没有将方面编织到您自己的代码中,因为您必须将库明确地放在方面路径中才能实现。顺便说一句,如果第三方库是方面增强的,它将依赖于AspectJ运行时Aspectjrt.jar,否则它将无法工作。即使运行时被隐藏在其他JAR中,您自己的代码也不会发生任何事情。
加载时间编织
您的应用程序不使用LTW:显然不会发生任何事情,如果您不使用活动的编织代理启动JVM,则其他JAR的任何方面都无法编织到您的代码中。
您的应用程序使用LTW:您将需要提供aop.xml文件,并且您可以在此处明确列出要应用的方面,哪些目标类或包要包含到编织中或从编织中排除,请打开-showWeaveInfo
以便也能看到在控制台上将哪些方面编织到哪些连接点中。但是,有一个警告:如果AspectJ编织者在类路径上找到多个aop.xml或aop-ajc.xml文件,它将在概念上合并它们。即如果第三方库随附了此类文件,则该文件将按照AspectJ development guide中的说明合并到您自己的文件中(在页面上搜索“多个配置文件”)。因此,这可能会导致一些不良后果。如果要检查第三方库,最简单的操作是分别扫描JAR中是否存在aop.xml或aop-ajc.xml。然后,您可以查看这些文件的内容(如果有),并轻松评估它们对代码的可能影响。但是,只要在应用程序启动时检查-showWeaveInfo
的输出,还可以发现是否将不需要的方面编织到了自己的代码中。
因此,实际上您不需要扫描类文件中的任何内容即可检测AspectJ标记,但是如果您绝对希望这样做,可以执行以下操作:
大多数AspectJ编织的类都包含字段或方法(可以是静态或非静态,私有或公共的),其名称中通常在开头带有ajc$
。那只是一种启发式方法,但是嘿-不管用什么,对不对?
如果我说“大多数类”,则是指在某些情况下,如果某个方面仅使用ITD来使一个类实现接口,引入新方法或公共字段,则该类将仅获取新元素,而没有AspectJ专用代码。但是,它们只是普通的类,没有交叉的建议代码或任何可能影响您自己的应用程序的代码。
如果您找到这样的成员或字段,则表明您或者找到了由方面增强的类(即使在带有额外aop.xml的LTW场景中也不会影响您自己的类)或方面本身,因为它们还包含相同的标记,您可以扫描的其他一些东西。
那么,如何扫描这些第三方类文件?
命令行:javap -p path/to/MyClass.class | grep 'ajc[$]'
扫描已经加载到(测试或检查)应用程序中的类的Java代码:
package de.scrum_master.aspect;
import java.lang.reflect.Member;
import java.util.stream.Stream;
public class AspectJDetector {
public static boolean hasAspectJMarker(Class<?> clazz) {
return Stream.concat(
Stream.of((Member[]) clazz.getDeclaredMethods()),
Stream.of((Member[]) clazz.getDeclaredFields())
)
.filter(member -> member.getName().contains("ajc$"))
.findFirst()
.isPresent();
}
}
只需为要检查的每个班级拨打
hasAspectJMarker(MyClassOfInterest.class)
。如果您找到了AspectJ增强的类,则无需担心。只有找到方面,才有可能。但是正如我上面所说:通过该JAR中的aop.xml可以更容易地检测到它。 XML文件甚至可以通过<aspect name="com.MyAspect"/>
明确列出各个方面,这基本上是显而易见的。
关于java - 使用字节伙伴代理按AspectJ检测编织的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57811860/