Bean 定義 DSL
Spring Framework は、XML または Java 構成(@Configuration
および @Bean
)の代替としてラムダを使用することにより、関数方法で Bean を登録することをサポートします。簡単に言うと、FactoryBean
として機能するラムダを使用して Bean を登録できます。このメカニズムは、リフレクションまたは CGLIB プロキシを必要としないため、非常に効率的です。
Java では、たとえば、次のように記述できます。
class Foo {}
class Bar {
private final Foo foo;
public Bar(Foo foo) {
this.foo = foo;
}
}
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean(Foo.class);
context.registerBean(Bar.class, () -> new Bar(context.getBean(Foo.class)));
Kotlin では、具体化された型パラメーターと GenericApplicationContext
Kotlin 拡張を使用して、代わりに次のように記述できます。
class Foo
class Bar(private val foo: Foo)
val context = GenericApplicationContext().apply {
registerBean<Foo>()
registerBean { Bar(it.getBean()) }
}
クラス Bar
に単一のコンストラクターがある場合、Bean クラスを指定するだけで、コンストラクターパラメーターは型ごとにオートワイヤーされます。
val context = GenericApplicationContext().apply {
registerBean<Foo>()
registerBean<Bar>()
}
より宣言的なアプローチとより簡潔な構文を可能にするために、Spring Framework は Kotlin Bean 定義 DSL (英語) を提供し、クリーンな宣言 API を介して ApplicationContextInitializer
を宣言します。これにより、Bean の登録方法をカスタマイズするためのプロファイルと Environment
を処理できます。
次の例では、次のことに注意してください。
通常、型推論により、
ref("bazBean")
などの Bean 参照の型の指定を回避できます。この例では、Kotlin トップレベル関数を使用して、
bean(::myRouter)
などの呼び出し可能参照を使用して Bean を宣言することができます。bean<Bar>()
またはbean(::myRouter)
を指定すると、パラメーターは型ごとにオートワイヤーされます。FooBar
Bean は、foobar
プロファイルがアクティブな場合にのみ登録されます
class Foo
class Bar(private val foo: Foo)
class Baz(var message: String = "")
class FooBar(private val baz: Baz)
val myBeans = beans {
bean<Foo>()
bean<Bar>()
bean("bazBean") {
Baz().apply {
message = "Hello world"
}
}
profile("foobar") {
bean { FooBar(ref("bazBean")) }
}
bean(::myRouter)
}
fun myRouter(foo: Foo, bar: Bar, baz: Baz) = router {
// ...
}
この DSL はプログラムです。つまり、if 式、for ループ、その他の Kotlin 構成体を介して Bean のカスタム登録ロジックを許可します。 |
次の例に示すように、この beans()
関数を使用して、アプリケーションコンテキストに Bean を登録できます。
val context = GenericApplicationContext().apply {
myBeans.initialize(this)
refresh()
}
Spring Boot は JavaConfig に基づいており、まだ関数 Bean 定義の特定のサポートを提供していません [GitHub] (英語) が、Spring Boot の ApplicationContextInitializer サポートを通じて関数 Bean 定義を実験的に使用できます。詳細と最新情報については、このスタックオーバーフローの回答 (英語) を参照してください。Spring Fu インキュベーター [GitHub] (英語) で開発された実験的な Kofu DSL も参照してください。 |