我想替换一些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?到目前为止,我仅找到了有关如何为被呼叫者而不是呼叫者进行检测的示例。
答案 0 :(得分:1)
您当前可以通过注册MemberSubstitution
来替换方法或字段访问,但是与AspectJ相比,该功能仍然受到限制。例如,不可能像示例代码中那样引发异常。但是,您可以委托一个方法,该方法将包含引发异常的代码:
MemberSubstitution.relaxed()
.method(named("currentTimeMillis"))
.replaceWith(MyClass.class.getMethod("throwException"))
.in(any());
上面的替换将用对以下成员的调用替换任何方法调用:
public class MyClass {
public static long throwException() {
throw new IllegalStateException();
}
}
该替换将应用于访问者所应用的任何方法。您可以注册AgentBuilder.Default
来构建Java代理来这样做,也可以查看Byte Buddy的构建插件。