Вопрос

Я создаю прокси с Javassist ProxyFactory. Отказ При создании одного прокси все работает нормально.

Однако, когда я передаю прокси-объект к механизму прокси, оно не справится с

JavAssist.bytecode.duplicateMemberexception: дубликат метод: sethandler в com.mypackage.bean _ $$ _ javassist_0 _ $$ _ javassist_1

Я создаю прокси с этим:

public Object createProxiedInstance(Object originalInstance) throws Exception {
    Class<?> originalClass = instance.getClass();
    ProxyFactory factory = new ProxyFactory();

    factory.setSuperclass(originalClass);

    factory.setHandler(new MethodHandler() {..});
    Class<T> proxyClass = factory.createClass();

    return proxyClass.newInstance();
}

Итак, как мне создать прокси прокси?

Обновлять: Фактические проблемы заключаются в том, что каждый прокси реализует ProxyObject который определяет setHandler(..) метод. Таким образом, 2-й прокси пытается переопределить метод, вместо того, чтобы переопределить его в подклассе.

Это было полезно?

Решение

Проблема была (на самом деле, это то же самое с CGLIB - я попробовал его использовать Commons-Proxy), что я не должен пытаться создать прокси-класс прокси-класса. Второй прокси должен снова иметь первоначальный класс. Так что добавление следующей строки решает проблему:

if (instance instanceof ProxyObject) {
    originalClass = originalClass.getSuperclass();
}

И совет - если вы можете использовать некоторые перехватыватели (например, те, которые определены в Commons-Proxy), выполните его вместо того, чтобы использовать несколько прокси.

Другие советы

Это довольно поздний ответ, но вы все еще могут быть заинтересованы в том, чтобы знать это:

Жавассисты прокси реализованы довольно наивно. В вашем вышеуказанном коде Javassist всегда будет создавать прокси-класс со следующими способами:

  1. Способ для любого переопределенного метода базового класса
  2. Два метода (а) получить обработчик прокси (getHandler) и (b) Установите обработчик прокси (setHandler)

Имена двух последних методов жесткодируются Javassist и представлены ProxyObject интерфейс. Если вы сейчас создаете прокси класс прокси-класса, Javassist будет запланировать создание ProxyObjectметоды дважды. Один раз по первым условиям и один раз на второе условие.

Вы можете избежать этого, установив MethodFilter который указывает, чтобы не переопределить ProxyObjectМетоды, такие, как Javassist создадут только методы во втором состоянии. Тем не менее, это подразумевает, что вы не могли бы больше не установить ProxyObject Для прокси сверх класса без прямого доступа к соответствующему полю через отражение. Поэтому ваш подход, вероятно, самый чистый.

CGLIB определяет обратные вызовы на класс, а не на случай, так что эта проблема с CGLIB немного отличается, но приводит к другому конфликту.

Однако, если вы хотите создать прокси-классы, которые не страдают эти недостатки, вы можете быть заинтересованы в моей библиотеке Байт Бадди. Что я написал после разочарованной работы с CGLIB и Javassist при работе в угловых случаях. Если вы работаете со скоростью кода выполнения, я надеюсь, что это может помочь предложить вам некоторую гибкость, что другие библиотеки отсутствуют.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top