Инструменты байт-кода: добавить метод-перехватчик к классам (не прокси)
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"));