2009-07-28 18 views
8

私は、春に配線されていないクラスでは、であるクラスを取得する必要があるレガシーコードベースを扱っています。私は起動時にワイヤリングされたファクトリクラスを作成し、次にgetInstance()メソッドを呼び出してワイヤードアップオブジェクトを取得することができます。これについて最善の方法は何ですか?Spring Wire静的クラス

例:私は起動時にアップ配線するFooFactoryを必要

public class LegacyA { 
    public void doSomething() { 
     ... 
     Foo foo = FooFactory.getInstance(); 
     ... 
    } 
} 

public class FooFactory { 
    private static Foo foo; 

    public static Foo getInstance() { 
     if (foo == null) throw new IllegalStateException(); 
     return foo; 
    } 
} 

それはまた、アプリケーション・コンテキストに定義された豆ではFooのインスタンスを(返すようLegacyAは、単にのgetInstance()を呼び出すことができます)。

<bean id="legacyA" class="LegacyA"/> 

<bean id="foo" class="Foo"/> 

<!-- I need this bean to be injected with foo so that the FooFactory can return a foo --> 
<bean id="fooFactory" class="FooFactory"/> 

編集:私はそれは少しは自分の頭の中でconfuzzledだと私は...再働く私の例にビットを持っていた

+0

FooはFooFactoryにどのように注入されましたか?セッター、コンストラクタ、...? – wds

答えて

10

は本当に春のIoCの穀物に反するが、あなたは本当には、それらを使用するを持っている場合、私は、例えば、Fooを取り、FooFactoryにそれを注入シンプルな春のフックを書くことをお勧め

public class FooFactoryProcessor implements InitializingBean { 

    private Foo foo; 

    public void setFoo(Foo foo) { 
     this.foo = foo; 
    } 

    public void afterPropertiesSet() throws Exception { 
     Foofactory.setFoo(foo); 
    } 
} 

そして、あなたのXMLで:

<bean id="foo" class="Foo"/> 

<bean class="FooFactoryProcessor"> 
    <property name="foo" ref="foo"/> 
</bean> 

skaffmanの答えに加えてFooまたはFooFactory

+0

はあなたの静的なコメントに関して合意しました。私は通常、そのルートを辿ることはありませんが、レガシーコードはこの静的クラスを使用しています。既存のコードを壊さずにこの新しい春オブジェクトをフックする最善の方法は、古い静的クラスへの呼び出しを保持し、クラスの新しく改良されたスプリング有線オブジェクトを使用します。 – digiarnie

+2

FooFactoryを春に直接管理させるのはなぜですか?あなたは本当に "FooFactoryProcessor"という抽象化を必要としません。 FooFactoryに静的でないプロパティ設定ツールを追加してfooを設定することができます。 –

+0

これは当てはまりますが、私はレガシーコードへの変更が最も少ないラインに沿って進んでいました。これはOPが後になったように見えます。 – skaffman

1

は、使用のSpring構成でsingletonとしてBeanを定義していますここに ?プロパティまたはコンストラクタインジェクション(私の設定は後者です)を使用してLegacyBに注入し、1つのインスタンスのみを使用できます。

EDIT:Re。あなたの変更された質問(!)私はあなたが単にあなたの工場にシングルトンとして再びFooを注入しないのか分かりません。また、factory-methodを使用して、getInstance()メソッドをSpringコンフィグレーションで使用し、すべてのクラスを通して注入を維持することもできます。このような静力学を使用して

+0

あなたの質問を少し変更する必要があり、申し訳ありません。私は私の頭の中で全体の質問が間違っていたより少し遅くまで気付かなかった。 – digiarnie

+0

ヘッドアップありがとう。それは問題じゃない。回答は適切に修正されました。 –

1

を変更する必要はありませんあなたは、初期化の順序について非常に非常に慎重でなければなりません。

Spring Beanを使用する場合、フレームワークは自動的に正しいものを初期化する正しい順序を見つけます。しかし、シングルトンのトリックをやっているとすぐに、これは慎重でないと壊れることがあります。

つまり、アプリケーションコンテキストのロードが完了する前に、LegacyAを実行できないようにしてください。