是否有可能解除Spring bean的问题?

时间:2011-11-14 12:25:40

标签: java spring

我有一个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",因为它打破了很多其他bean(这个属性会影响上下文中的所有bean)。

有没有办法取消注入注入的bean A,所以我可以将其转换为AImpl

2 个答案:

答案 0 :(得分:22)

试试这个:

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
}

答案 1 :(得分:11)

随着Spring 4.2.RC1的推出,spring-test模块中现在有一个专用的实用工具类,可以为你处理这个案例。

该类名为AopTestUtils并提供方法:

  • getTargetObject(仅展开顶级代理)
  • getUltimateTargetObject(如果存在多个代理级别,则解包。)

查看相关的commit以及相应的issue