如何在 Spring Boot 和 Spring WebFlux 中使用“功能 bean 定义 Kotlin DSL”?
Posted
技术标签:
【中文标题】如何在 Spring Boot 和 Spring WebFlux 中使用“功能 bean 定义 Kotlin DSL”?【英文标题】:How to use "Functional bean definition Kotlin DSL" with Spring Boot and Spring WebFlux? 【发布时间】:2018-02-06 17:20:56 【问题描述】:https://github.com/spring-projects/spring-framework/blob/master/spring-context/src/main/kotlin/org/springframework/context/support/BeanDefinitionDsl.kt 的评论显示了如何通过新的“功能 bean 定义 Kotlin DSL”来定义 Spring Bean。我还找到了https://github.com/sdeleuze/spring-kotlin-functional。但是,此示例仅使用 plain Spring 而不是 Spring Boot。任何关于如何将 DSL 与 Spring Boot 一起使用的提示都值得赞赏。
【问题讨论】:
你有没有试过,例如通过将此 bean 定义放入控制器(由 spring boot 发现)? 是的,我尝试了一个带有@Bean
方法的@Configuration
类,该方法返回beans ...
的结果。然后,当我删除 @Service
并在上面的 beans ...
lambda 中声明服务类时,我得到了异常 "... No qualifying bean of type '...' available ..."
。
【参考方案1】:
Spring Boot 基于 Java Config,但应允许通过 ApplicationContextInitializer
支持对用户定义的 functional bean declaration DSL 进行实验性支持,如 here 所述。
实际上,您应该能够在包含 beans()
函数的 Beans.kt
文件中声明您的 bean。
fun beans() = beans
// Define your bean with Kotlin DSL here
然后为了让Boot在运行main()
和测试时考虑到它,创建一个ApplicationContextInitializer
类如下:
class BeansInitializer : ApplicationContextInitializer<GenericApplicationContext>
override fun initialize(context: GenericApplicationContext) =
beans().initialize(context)
最后,在你的 application.properties
文件中声明这个初始化器:
context.initializer.classes=com.example.BeansInitializer
您将找到完整的示例 here,也可以关注 this issue,了解 Spring Boot 对功能性 bean 注册的支持。
【讨论】:
关于您的答案的两个问题: * 测试设置将使用SpringRunner
和 JUnit 来获取此初始化,对吗? * 是否有任何其他方法可以在不必创建properties
文件的情况下实现此行为,包括在测试中获取此初始化?谢谢!
是,但还没有。
旁注:我们目前正在github.com/spring-projects/spring-fu 孵化器项目中探索使用 Java 或 Kotlin DSL 的完整功能 bean 定义。
如果我想覆盖一个bean怎么办?我添加了 allow-bean-definition-overriding: true 并试图通过 @Bean 声明一个测试 bean,但它似乎被忽略了。我在没有otu bean DSL的项目上尝试了完全相同的设置(基本上,只是复制粘贴)并且它有效。
像这样声明初始化程序会禁用 Spring Boot 提供的所有其他初始化程序,不是吗?【参考方案2】:
在 Spring Boot 中执行此操作的另一种方法是:
fun main(args: Array<String>)
runApplication<DemoApplication>(*args)
addInitializers(
beans
// Define your bean with Kotlin DSL here
)
【讨论】:
这种方法的缺点是初始化器不会被考虑到测试中。【参考方案3】:您可以在 *Config.kt 文件中定义您的 bean,并实现 ApplicationContextInitializer 接口的 initalize 方法。
override fun initialize(applicationContext: GenericApplicationContext)
....
这里有一些 bean 定义。
bean<XServiceImpl>("xService")
bean("beanName")
BeanConstructor(ref("refBeanName"))
【讨论】:
以上是关于如何在 Spring Boot 和 Spring WebFlux 中使用“功能 bean 定义 Kotlin DSL”?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Boot 和 Spring WebFlux 中使用“功能 bean 定义 Kotlin DSL”?
Spring Boot . 3 -- Spring Boot Auto_configuration 是如何实现的?
如何使用 Spring-Boot 播种 Spring-Security