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

MaD*_*aDa 20 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"/>
Run Code Online (Sandbox Code Playgroud)

现在我想集成测试它,但首先我需要模拟依赖D,因为它做了太多的东西.由于AImpl实现了一个接口并包含一个事务注释,生成的代理只与接口兼容A,所以我可以这样做:

@Inject @Named("aImpl")
private A a;
Run Code Online (Sandbox Code Playgroud)

但不能:

@Inject @Named("aImpl")
private AImpl a;
Run Code Online (Sandbox Code Playgroud)

结果,我无法模仿我的依赖.

请注意,添加void setSomeDependency(D dependency)到界面A不是一个选项,因为它没有商业含义.它都没有使用proxy-target-class="true",因为它打破了很多其他bean(这个属性会影响上下文中的所有bean).

有没有办法解开注入的bean A,所以我可以把它投射到AImpl

Tom*_*icz 26

试试这个:

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

额外奖励:在Scala中,我使用以下等效函数用于同一目的:

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

  • 谢谢,你真的救了我.顺便说一句,我刚刚第一次访问奥斯陆,现在我不知道为什么你花了那么多时间在SO上(没有冒犯意味着,但天气并不令人鼓舞):) (8认同)
  • 很高兴我能帮助你.我非常喜欢你的评论,甚至在我的个人资料页面引用它;-). (2认同)

geo*_*and 14

随着Spring 4.2.RC1的引入,spring-test模块中现在有一个专用的实用程序类,可以为您处理这种情况.

调用该类AopTestUtils并提供方法:

  • getTargetObject (仅展开顶级代理)
  • getUltimateTargetObject (如果存在多个代理级别,则展开它们).

查看相关提交以及相应的问题.

  • 感谢您提供更新的答案,这对大多数人来说是一个更好的解决方案,因为它需要更少的逻辑。 (3认同)