Как создать прокси с настраиваемым полем, используя 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 вы можете альтернативно добавить функцию обратного вызова для делегирования в конкретный экземпляр средства расширения для каждого отдельного прокси-сервера, используя класс обратного вызова.

Другие вопросы по тегам