字节码工具:将方法拦截器添加到类(不是代理)

时间:2017-11-03 14:45:41

标签: javassist cglib byte-buddy method-interception

Javassist proxyFactory可以在运行时使用方法拦截器创建代理。但是如何通过修改类文件静态地将方法拦截器添加到类中?

例如,类Foo有100个方法,在调用Foo实例上的任何方法之前,需要检查Foo实例是否已初始化。

public class Foo {

    public void methodA() {
        ...
    }

    public void methodB() {
        ...
    }

    public void methodC() {
        ...
    }

    ....
}

如何修改类文件添加这样的方法拦截器?一种方法是在每个方法的开头添加代码。还有更好的方法吗?

其他字节码工具如cglib,....?

1 个答案:

答案 0 :(得分:0)

ByteBuddy有两种方法可以实现这一目标:

  • 使用redefine / rebase功能 - 您可以在'type redefinition'/'type rebasing'标记下查看ByteBuddy tutorial的详细信息。这里的局限是需要在加载目标类之前完成这种转换。
  • Java代理 - 代理在加载类之前运行,因此允许它们修改现有的类。 ByteBuddy带有很好的AgentBuilder(tutorial - '创建Java代理')。在运行时也可以安装特殊的ByteBuddy代理(例如,在提到的教程中)。

    class Foo {
      String m() { return "foo"; }
    }
    
    class Bar {
      String m() { return "bar"; }
    }
    
    ByteBuddyAgent.install();
    Foo foo = new Foo();
    new ByteBuddy()
      .redefine(Bar.class)
      .name(Foo.class.getName())
      .make()
      .load(Foo.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
    assertThat(foo.m(), is("bar"));