如何在 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和Spring Boot的属性

Spring Boot . 3 -- Spring Boot Auto_configuration 是如何实现的?

如何使用 Spring-Boot 播种 Spring-Security

如何隔离spring boot app redis和spring boot session全局redis

如何解决 CockroachDB 和 Spring-Boot 的密码问题