可以使用ByteBuddy代替调用的方法来检测方法调用吗?

时间:2019-09-05 15:15:30

标签: java scala aspectj byte-buddy

我想替换一些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?到目前为止,我仅找到了有关如何为被呼叫者而不是呼叫者进行检测的示例。

1 个答案:

答案 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的构建插件。