Возможно ли использовать unproxy a Spring bean? - программирование
Подтвердить что ты не робот

Возможно ли использовать unproxy a Spring bean?

У меня есть Spring bean, скажем:

@TransactionAttribute(TransactionAttributeType.REQUIRED) 
public class AImpl implements A {

     public void setSomeDependency(D dependency) {
         // This setter DOES NOT BELONG to interface A
     }
}

<bean id="aImpl" class="AImpl"/>

Теперь я хочу, чтобы интеграция протестировала его, но сначала мне нужно высмеять зависимость D, потому что это слишком много. Поскольку AImpl реализует интерфейс и содержит транзакционную аннотацию, сгенерированный прокси совместим только с интерфейсом A, поэтому я могу это сделать:

@Inject @Named("aImpl")
private A a;

но не может:

@Inject @Named("aImpl")
private AImpl a;

В результате я не могу издеваться над своей зависимостью.

Обратите внимание, что добавление void setSomeDependency(D dependency) в интерфейс A не является опцией, поскольку оно не имеет никакого коммерческого значения. Он также использует proxy-target-class="true", поскольку он разбивает много других beans (этот атрибут влияет на все beans в контексте).

Есть ли способ отключить введенный bean A, поэтому я мог бы применить его к AImpl?

4b9b3361

Ответ 1

Попробуйте следующее:

if(AopUtils.isAopProxy(a) && a instanceof Advised) {
    Object target = ((Advised)a).getTargetSource().getTarget();
    AImpl ai = (AImpl)target;
}

Бонус: в Scala Я использую следующую эквивалентную функцию для той же цели:

def unwrapProxy(a: AnyRef) = a match {
    case advised: Advised if(AopUtils.isAopProxy(advised)) => 
                            advised.getTargetSource.getTarget
    case notProxy => notProxy
}

Ответ 2

С введением Spring 4.2.RC1 в модуле spring-test есть выделенный класс утилиты, который обрабатывает этот случай для вас.

Класс называется AopTestUtils и предоставляет методы:

  • getTargetObject (разворачивает только прокси верхнего уровня)
  • getUltimateTargetObject (разворачивает несколько уровней прокси, если они существуют).

Просмотрите соответствующий commit, а также соответствующую проблему.