2011-11-14 3 views
15

私は春の豆を持っている、のは言わせて: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; 

、私は私の依存を嘲笑することはできません。

インタフェースAvoid setSomeDependency(D dependency)を追加することは、ビジネス上の意味がないため、オプションではありません。 proxy-target-class="true"を使用していません。これは、他のBean全体を壊すためです(この属性は、コンテキスト内のすべてのBeanに影響します)。

注入されたBeanをプロンプト解除する方法はありますか?Aですので、AImplにキャストできますか?

+0

[SpringのProxyオブジェクトを実際のランタイムクラスにキャストする]の複製が可能です(http://stackoverflow.com/questions/5976247/casting-a-springs-proxy-object-to-the-actual-runtime-class ) – skaffman

+0

@skaffman:それを指摘してくれてありがとう、私は春のタグに質問を追加しましたよくある質問 –

答えて

22

これを試してみてください:

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

ボーナス:Scalaで、私は非常に同じ目的のために、以下の同等の機能を使用しています:

春4.2.RC1の導入により
def unwrapProxy(a: AnyRef) = a match { 
    case advised: Advised if(AopUtils.isAopProxy(advised)) => 
          advised.getTargetSource.getTarget 
    case notProxy => notProxy 
} 
+8

ありがとう、あなたは本当に私を救った。私はちょうど初めてオスロを訪れましたが、今はあなたがなぜそんなに多くの時間を費やしているのか不思議ではありません(犯罪はありませんが、天気は奨励されません):) – MaDa

+2

嬉しいです。あなたのコメントがとても好きで、私のプロフィールページでも引用しました;-)。 –

8

は、今そこにありますあなたのためにこのケースを処理するspring-testモジュールの専用ユーティリティクラスです。

クラスは、AopTestUtilsと呼ばれる方法を提供される:

  • getTargetObject(のみ最上位プロキシをアンラップ)
  • getUltimateTargetObject(それらが存在する場合、プロキシの複数のレベルをアンラップ)。

commitとそれぞれissueを確認してください。

関連する問題