Выделение объекта Spring Proxy для реального класса выполнения

Я использую Spring, в какой-то момент я хотел бы передать объект в его фактическую реализацию выполнения.

Пример:

Class MyClass extends NotMyClass {
    InterfaceA a;
    InterfaceA getA() { return a; }

    myMethod(SomeObject o) { ((ImplementationOfA) getA()).methodA(o.getProperty()); }
}

Это кричит a ClassCastException, так как a является объектом $ProxyN. Хотя в beans.xml я ввел bean, который имеет класс ImplementationOfA.

РЕДАКТИРОВАТЬ 1 Я расширил класс, и мне нужно вызвать метод в ImplementationOfA. Поэтому я думаю, что мне нужно бросить. Метод получает параметр.

РЕДАКТИРОВАТЬ 2

Лучше сорвать целевой класс:

private T getTargetObject(Object proxy, Class targetClass) throws Exception {
    while( (AopUtils.isJdkDynamicProxy(proxy))) {
        return (T) getTargetObject(((Advised)proxy).getTargetSource().getTarget(), targetClass);
    }
    return (T) proxy; // expected to be cglib proxy then, which is simply a specialized class
}

Я знаю, что это не очень элегантно, но работает.

Все кредиты http://www.techper.net/2009/06/05/how-to-acess-target-object-behind-a-spring-proxy/ Спасибо!

Ответы

Ответ 2

Для меня версия от EDIT 2 не работала. Ниже работало:

@SuppressWarnings({"unchecked"})
protected <T> T getTargetObject(Object proxy) throws Exception {
    while( (AopUtils.isJdkDynamicProxy(proxy))) {
        return (T) getTargetObject(((Advised)proxy).getTargetSource().getTarget());
    }
    return (T) proxy; // expected to be cglib proxy then, which is simply a specialized class
}

Использование:

    UserServicesImpl serviceImpl = getTargetObject(serviceProxy);
    serviceImpl.setUserDao(userDAO);

Ответ 3

Теперь вы можете использовать

AopTestUtils.getTargetObject(proxy)
.

Реализация та же, что и у @siulkilulki sugestion, но это на Spring helper

Ответ 4

В основном, когда вы используете AOP в Spring, Spring создает Proxy для вас. У вас есть два варианта:

  1. когда вы применяете аспект к бину, который реализует интерфейс, в этом случае Spring использует JdkDynamicProxy
  2. когда ваш bean-компонент Spring не реализует какой-либо интерфейс и если у вас есть cglib 2.2 в вашем classpath, учтите, что из Spring 3.2.x у вас есть cglib в контейнере Spring по умолчанию, Spring использует специальный прокси-сервер CGLibProxy.

Ключевым моментом здесь является то, что когда аспект применяется к вашему бобу, Spring создает экземпляр прокси, и если вы попытаетесь выполнить приведение, вы получите исключение.

Я надеюсь, что это может помочь вам