Spring Framework 支持使用 lambda 以功能方式注册 bean 作为 XML 或 Java 配置 ( 和 ) 的替代方法。简而言之 它允许您使用充当 . 这种机制非常有效,因为它不需要任何反射或 CGLIB 代理。@Configuration@BeanFactoryBeanspring-doc.cn

例如,在 Java 中,您可以编写以下内容:spring-doc.cn

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 中,使用具体化的类型参数和 Kotlin 扩展, 您可以改为编写以下内容:GenericApplicationContextspring-doc.cn

class Foo

class Bar(private val foo: Foo)

val context = GenericApplicationContext().apply {
	registerBean<Foo>()
	registerBean { Bar(it.getBean()) }
}

当类只有一个构造函数时,您甚至可以只指定 bean 类 构造函数参数将按类型自动装配:Barspring-doc.cn

val context = GenericApplicationContext().apply {
	registerBean<Foo>()
	registerBean<Bar>()
}

为了实现更具声明性的方法和更简洁的语法, Spring Framework 提供了 一个 Kotlin bean 定义 DSL 它通过一个干净的声明式 API 声明了一个 它允许您处理配置文件和自定义 如何注册 bean。ApplicationContextInitializerEnvironmentspring-doc.cn

在以下示例中,请注意:spring-doc.cn

  • 类型推断通常允许避免为 bean 引用指定类型,例如ref("bazBean")spring-doc.cn

  • 可以使用 Kotlin 顶级函数通过可调用引用来声明 bean,如本例所示bean(::myRouter)spring-doc.cn

  • 指定 或 时,参数将按类型自动装配bean<Bar>()bean(::myRouter)spring-doc.cn

  • 仅当配置文件处于活动状态时,才会注册 BeanFooBarfoobarspring-doc.cn

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 是编程的,这意味着它允许自定义 bean 的注册逻辑 通过表达式、循环或任何其他 Kotlin 构造。iffor
此 DSL 是编程的,这意味着它允许自定义 bean 的注册逻辑 通过表达式、循环或任何其他 Kotlin 构造。iffor

然后,您可以使用此函数在应用程序上下文中注册 bean。 如下例所示:beans()spring-doc.cn

val context = GenericApplicationContext().apply {
	myBeans.initialize(this)
	refresh()
}
Spring Boot 基于 JavaConfig,尚未为函数式 bean 定义提供特定支持。 但是你可以通过 Spring Boot 的支持来实验性地使用函数式 bean 定义。 有关更多详细信息和最新信息,请参阅此 Stack Overflow 答案。另请参阅在 Spring Fu 培养箱中开发的实验性 Kofu DSL。ApplicationContextInitializer
Spring Boot 基于 JavaConfig,尚未为函数式 bean 定义提供特定支持。 但是你可以通过 Spring Boot 的支持来实验性地使用函数式 bean 定义。 有关更多详细信息和最新信息,请参阅此 Stack Overflow 答案。另请参阅在 Spring Fu 培养箱中开发的实验性 Kofu DSL。ApplicationContextInitializer