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 も参照してください。