Как создать прокси с настраиваемым полем, используя cglib?
Я использую cglib для создания прокси-объекта некоторого класса, и мне нужно привязать некоторые обычные поля к прокси-объекту, как показано ниже
String customFieldName = "myCustomField";
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(targetClass);
// What can I do to add custom field to the proxy class ?
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
// I'd access the custom field value here
Field field = obj.getClass().getField(customFieldName);
Object customFieldValue = field.get(obj);
// do something
return proxy.invokeSuper(obj, args);
}
});
Конечно, альтернативой является использование карты для привязки значения к исходному объекту, но мне не очень нравится это делать.
У кого-нибудь есть идеи?
1 ответ
Это невозможно при использовании cglib, для него нет API, если вы не хотите получить доступ к базовому API ASM, чтобы добавить поле непосредственно в байт-код. Если вы готовы поменять инструмент, вы можете использовать Byte Buddy, библиотеку, которую я поддерживаю:
Class<? extends TargetClass> proxy = new ByteBuddy()
.subclass(targetClass)
.method(any())
.intercept(MethodDelegation.to(MyInterceptor.class)
.andThen(SuperMethodCall.INSTANCE)
.defineField("myCustomField", Object.class, Visibility.PUBLIC)
.make()
.load(targetClass.getClassLoader())
.getLoaded();
class MyInterceptor {
static void intercept(@FieldValue("myCustomField") Object myCustomField) {
// do something
}
}
С помощью cglib вы можете альтернативно добавить функцию обратного вызова для делегирования в конкретный экземпляр средства расширения для каждого отдельного прокси-сервера, используя класс обратного вызова.