【发布时间】:2019-09-05 15:15:30
【问题描述】:
我想替换一些 AspectJ 代码来保护对 java.lang.System 的调用不受某些用户代码的影响。
java.lang.System 不能/不应该被检测。
使用 AspectJ,解决方案是像以下示例一样检测调用代码。应该保护的代码将被检测,而允许的代码则不被检测。
@Around("call(public long java.lang.System.currentTimeMillis()) && within(io.someuserdomain..*) && !within(io.someotherdomain..*))
def aroundSystemcurrentTimeMillis(wrapped: ProceedingJoinPoint): Long = {
throw new IllegalStateException("must not call System.currentTimeMillis in usercode")
}
有没有办法使用 ByteBuddy 做同样的事情?到目前为止,我只找到了有关如何检测被调用者而不是调用者的示例。
【问题讨论】:
-
为什么要用ByteBuddy 替换AspectJ? AspectJ 运行时要小得多,并且没有其他依赖项。您想通过切换工具来解决什么问题?
-
对不起,我忘了量化我之前的陈述:AspectJ 运行时有 120K,ByteBuddy 打包依赖项有 3.2M。比较当前版本的 JAR,JAR 大小相差 27.5 倍,有利于 AspectJ。这并不意味着它是更好的工具,但对于您想要做的事情,它非常适合。如果使用编译时编织,您甚至可以在一个方面声明编译器警告或错误,以便在方面检测到非法方法调用时使编译失败。如果 CTW 是一个选项而不是 LTW,我会这样做,因为在运行时检测它是次优的。
-
@kriegaex 好问题。我们正在使用另一个从 aspectj 切换到 bytebuddy (kamon) 的库。在我们的代码库中,我们谨慎地使用 aspectj,并希望避免维护多个检测框架。至于讨论的用例——如果这是我唯一需要仪器的地方,我会选择 aspectj,因为它允许更大的灵活性。但是我当然有偏见,因为我经常使用 aspectj,而且我是 bytebuddy 的新手。在我从 aspectj 转换为 bytebuddy 的其他地方,bytebuddy 中的检测声明的类型安全性比 aspectj 更好。
-
我很惊讶你这么说类型安全。实际上,我从那些没有足够经验正确使用 AspectJ 的人那里看到了很多不好的方面代码,所以也许这就是它的来源。话虽如此,并承认我的支持 AspectJ 的偏见,因为我一直在使用它,但我确实同意 ByteBuddy 是一个强大的工具,并且毫无疑问,你也可以用它优雅地解决你的问题。 Rafael 的回答在我看来非常好,他在 SO 上提供了大力支持,他是 ByteBuddy 的作者。 :-) 祝你好运!
标签: java scala aspectj byte-buddy