Инструменты байт-кода: добавить метод-перехватчик к классам (не прокси)

Javassist proxyFactory может создавать прокси во время выполнения с методом-перехватчиком. Но как добавить метод-перехватчик в класс статически, изменив файл класса?

Например, класс Foo имеет 100 методов, и перед вызовом любого метода в экземпляре Foo необходимо проверить, инициализирован ли экземпляр Foo.

public class Foo {

    public void methodA() {
        ...
    }

    public void methodB() {
        ...
    }

    public void methodC() {
        ...
    }

    ....
}

Как изменить файл класса, чтобы добавить такой метод-перехватчик? Одним из способов является добавление кода в начале каждого метода. Есть ли способ лучше?

Как насчет других инструментов байт-кода, таких как cglib,....?

1 ответ

Есть два варианта с ByteBuddy для достижения этой цели:

  • использовать функцию переопределения / перебазирования - вы можете проверить подробности в руководстве ByteBuddy в тегах 'переопределение типа'/'перебазирование типа'. Ограничением здесь является то, что этот вид преобразования должен быть выполнен до загрузки целевого класса.
  • Агент Java - агенты запускаются до загрузки класса, поэтому им разрешено изменять существующие классы. ByteBuddy поставляется с отличным AgentBuilder ( учебник - "Создание агентов 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"));
    
Другие вопросы по тегам