java - beans - ¿Es posible unproxy un Spring bean?
tipos de beans spring (2)
Con la introducción de Spring 4.2.RC1, ahora hay una clase de utilidad dedicada en el módulo de spring-test
que maneja este caso por usted.
La clase se llama AopTestUtils
y proporciona los métodos:
-
getTargetObject
(desenvuelve solo el proxy de nivel superior) -
getUltimateTargetObject
(desenvuelve múltiples niveles de proxies si existen).
Echa un vistazo a la commit correspondiente, así como el issue respectivo.
Tengo un frijol de primavera, digamos:
@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"/>
Ahora quiero que la integración lo pruebe, pero primero necesito burlarme de la dependencia D
, porque hace demasiadas cosas. Como AImpl
implementa una interfaz y contiene una anotación transaccional, el proxy generado solo es compatible con la interfaz A
, así que puedo hacer esto:
@Inject @Named("aImpl")
private A a;
pero no puede:
@Inject @Named("aImpl")
private AImpl a;
Como resultado, no puedo burlarme de mi dependencia.
Tenga en cuenta que agregar void setSomeDependency(D dependency)
a la interfaz A
no es una opción, ya que no tiene significado comercial. Tampoco utiliza el proxy-target-class="true"
, ya que rompe un montón de otros beans (este atributo afecta a todos los beans en el contexto).
¿Hay una manera de desaprender el frijol A
inyectado, para poder AImpl
a AImpl
?
Prueba esto:
if(AopUtils.isAopProxy(a) && a instanceof Advised) {
Object target = ((Advised)a).getTargetSource().getTarget();
AImpl ai = (AImpl)target;
}
Bono: en Scala estoy usando la siguiente función equivalente para el mismo propósito:
def unwrapProxy(a: AnyRef) = a match {
case advised: Advised if(AopUtils.isAopProxy(advised)) =>
advised.getTargetSource.getTarget
case notProxy => notProxy
}