2016-10-31 11 views
0

Я использую 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); 
     } 
    }); 

Конечно альтернатива использует карту, чтобы связать значение объект происхождения, но я не очень люблю это делать.

У кого-нибудь есть идеи?

ответ

0

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