SpringのJava Configを使用して、実行時にのみ取得できるコンストラクター引数を使用して、プロトタイプスコープのBeanを取得またはインスタンス化する必要があります。次のコード例(簡潔にするために簡略化)を考えます。
@Autowired
private ApplicationContext appCtx;
public void onRequest(Request request) {
//request is already validated
String name = request.getParameter("name");
Thing thing = appCtx.getBean(Thing.class, name);
//System.out.println(thing.getName()); //prints name
}
ここで、Thingクラスは次のように定義されています。
public class Thing {
private final String name;
@Autowired
private SomeComponent someComponent;
@Autowired
private AnotherComponent anotherComponent;
public Thing(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
通知はname
ありfinal
、それが唯一のコンストラクタを介して供給することができ、かつ不変性を保証します:。その他の依存関係は、Thing
クラスの実装固有の依存関係であり、要求ハンドラーの実装に(密結合)してはなりません。
このコードは、たとえば、Spring XML構成で完全に機能します。
<bean id="thing", class="com.whatever.Thing" scope="prototype">
<!-- other post-instantiation properties omitted -->
</bean>
Java configで同じことをするにはどうすればよいですか?以下は、Spring 3.xを使用すると機能しません。
@Bean
@Scope("prototype")
public Thing thing(String name) {
return new Thing(name);
}
ここで、ファクトリを作成できます。例:
public interface ThingFactory {
public Thing createThing(String name);
}
ただし、これは、Springを使用してServiceLocatorおよびFactory設計パターンを置き換えるという全体のポイントを打ち負かします。これは、このユースケースに理想的です。
Spring Java Configがこれを行うことができれば、私は避けることができます:
- ファクトリインターフェースの定義
- ファクトリ実装の定義
- ファクトリ実装のテストを書く
これは、Springが既にXML構成を介してサポートしているほど簡単なものの(比較的言えば)大量の作業です。
Thing
実装は実際にはより複雑であり、他のBeanに依存しています(簡潔にするために省略しました)。そのため、リクエストハンドラーの実装がそれらについて知る必要はありません。これにより、ハンドラーが必要のないAPI / Beanに密接に結合されるからです。(優れた)質問を反映するように質問を更新します。
@Qualifier
でパラメーターをセッターに設定できることはわかっています@Autowired
。
@Bean
機能します。@Bean
この方法は、あなたがに渡された適切な引数で呼び出されますgetBean(..)
。