10

Spring では、applicationContext.xml でコンストラクターを呼び出すことによって Bean を初期化するか、Bean にプロパティを設定できます。2 つのアプローチのトレードオフは何ですか? コンストラクター (必要なものすべてを 1 つのメソッドで持つというコントラクトを強制する) を持つ方が良いですか、それともすべてのプロパティを持つ方が良いですか (これにより、たとえば単体テスト時に選択的にのみ注入する柔軟性が得られます)。

トレードオフは何ですか (コンストラクターを使用して初期状態を確立する Bean を作成するか、プロパティとおそらく afterProperties() メソッドを使用するかの間)?

4

5 に答える 5

15

Bean を初期化する「最良の」方法があるかどうかはわかりません。それぞれに一長一短があると思いますので、状況によってはどちらかが適切かもしれません。これは確かに完全なリストではありませんが、考慮すべき点がいくつかあります。

コンストラクターを使用すると、不変の Bean を持つことができます。不変オブジェクトは、設計に適合できる場合に適しています。スレッド間のコピー、シリアル化されたアクセス、またはその他の特別な処理は必要ありません。セッターがある場合、オブジェクトは不変ではありません。コンストラクターを使用すると、オブジェクトが適切に初期化されます。コンストラクターが終了すると、オブジェクトは有効になります。オブジェクトを初期化するためにセッターを使用する必要がある場合は、無効なオブジェクトが存在する可能性があります。

一方、コンストラクターを使用すると、テレスコーピングの問題が発生することがよくあります。多くの場合、多くの異なるコンストラクターが必要になりますが、そのほとんどは別のコンストラクターのスーパーセットになります。多くの場合、これらは便宜上のものです。例えば:

public class Person {
  public Person(String name) { ... }
  public Person(String name, String phone) { ... }
  public Person(String name, String phone, String email) { ... }
}

私が非常に気に入っている代替案の 1 つは、JavaOne で Josh Bloch によって提示された、いわゆる「強化された」ビルダー パターンです。これについては、彼の著書「Effective Java, Second Edition」で確認できます。パターンの使用方法を見ると、「afterProperties」メソッドの問題も解決します。ビルダー パターンは、オブジェクトが正しく初期化されることを保証します。

パターンについて説明している追加のブログ投稿を次に示します: http://www.screaming-penguin.com/node/7598

これがあなたの春の要件に合っているかどうかはわかりませんが、一般的に、私はビルダーの大ファンです.

于 2008-10-17T05:11:04.140 に答える
3

IMO コンストラクター注入の主な利点は、不変性と互換性があることです。ただし、クラスに約 3 つ以上の依存関係がある場合、多数のパラメーターを受け取るコンストラクターを提供する必要があり、扱いにくくなります。

セッター注入を使用する場合、@PostConstructアノテーションを使用して初期化メソッドを識別することを好みます。これには、あなたが言及した方法よりもSpringフレームワークへの結合が緩いことが含まれafterProperties()ます(実際には、そうだと思いますafterPropertiesSet())。もう 1 つのオプションは、<bean>要素の init メソッド属性です。

于 2008-10-17T04:50:23.730 に答える
2

現在使用しているバージョンはわかりませんが、Spring 2.5の場合は、特定の場合に@Autowiredアノテーションを使用することも検討できます。これは、粗いものは他のBeanへの参照に対してのみ機能し、lyconyの例のように文字列などに対しては機能しません。

これにより、セッターやコンストラクターの作成、および多くの構成の負担が軽減されます。少し例:

public class MyPersonBean {
  @Autowired
  private PersonManager personManager;

  public void doSomething() {
    this.personManager.doSomething();
  }
}

そしてあなたの設定ファイルで:

<context:annotation-config/>

自動配線はタイプごとに行われるため、PersonManagerタイプのBeanがある場合は、注釈付きフィールドに挿入されます。そのタイプのBeanがさらにある場合は、@Qualifierアノテーションを使用してそれらを区別できます...

自動配線の詳細については、Springリファレンスドキュメントを参照してください。

以前のプロジェクトでコンポーネントスキャンと組み合わせて@Autowiredを使い始めましたが、Spring構成ファイルの90%以上を削除したと言わざるを得ません。

于 2008-10-17T09:08:42.553 に答える
0

トレードオフ:

コンストラクター: 利点: 非常にシンプルにできます。初期化するプロパティが 3 つ以下の場合。ワンショットで、心配する余分な構成はありません/最小限です。

欠点: いくつかの状況で複数のコンストラクターを作成する必要がある コンストラクターは継承されないため、クラスは super() を呼び出して重複したコンストラクターを提供し、以前の動作を許可する必要があります。

セッター: 利点: 子はセッターを継承するため、プロパティを簡単にオーバーライドして、構築後の動作に影響を与えることができます。複数のプロパティは、異なるメソッド シグネチャ (JavaBeans 規則) を参照することなく、統一された方法で指定できます。

欠点: すべてのセッターは、すべてのプロパティに対して明示的に呼び出す必要があります。明示的に設定された多数のプロパティを持つ一部のクラスにつながります。

于 2008-10-18T03:42:31.573 に答える
0

@Resourceの代わりに to autowire を使用することもできます@Autowired。これは autowire byName のように機能するため、同じタイプの Bean が他にもある場合でも心配する必要はありません (ofc で処理することもできますが@Qualifier、豆の特徴)。どの方法が最適かはユースケースに大きく依存するため、状況に応じて評価し、後で決定する必要があります。

于 2009-01-22T15:52:41.113 に答える