Spring Boot 2、Spring Framework 5下Kotlin Beans DSL默认AutowireMode配置
为Spring Kotlin Beans DSL设置默认AutowireMode的解决方案
我之前维护遗留Spring项目时也碰到过一模一样的问题——几百个bean逐个指定autowireMode实在太繁琐了,下面给你两个实用的方案来解决这个重复配置的问题:
方案一:修改Beans DSL块的全局默认配置
Spring Kotlin的BeanDefinitionDsl(也就是beans代码块的上下文)提供了defaultAutowireMode属性,我们可以直接在块内设置全局默认的自动装配模式,这样所有在该块中定义的bean都会继承这个配置,除非你单独指定覆盖规则。
代码示例:
import org.springframework.context.support.beans import org.springframework.context.support.BeanDefinitionDsl fun beans() = beans { // 设置全局默认自动装配模式为BY_NAME this.defaultAutowireMode = BeanDefinitionDsl.Autowire.BY_NAME.value // 现在定义bean无需重复指定autowireMode bean<BeanImpl>() bean<AnotherBeanImpl>() // 几百个其他bean都可以这样简洁定义... // 如果某个bean需要特殊配置,依然可以单独指定覆盖默认值 bean<SpecialBean>(autowireMode = BeanDefinitionDsl.Autowire.BY_TYPE) }
这个方案最直接高效,适合大部分场景,只需要在beans块开头加一行配置就能解决重复代码的问题。
方案二:自定义扩展函数封装bean注册逻辑
如果你的场景更灵活——比如需要在多个beans块中复用相同的自动装配规则,或者想给这类bean起个更语义化的名称,可以自定义一个扩展函数来包装原有的bean方法:
import org.springframework.context.support.BeanDefinitionDsl import org.springframework.context.support.beans // 自定义扩展函数,默认使用BY_NAME自动装配 fun <T : Any> BeanDefinitionDsl.namedAutowireBean(name: String? = null, init: (T.() -> Unit)? = null) { bean<T>(name = name, autowireMode = BeanDefinitionDsl.Autowire.BY_NAME, init = init) } // 使用示例 fun beans() = beans { // 用自定义函数注册bean,自动应用BY_NAME模式 namedAutowireBean<BeanImpl>() namedAutowireBean<AnotherBeanImpl>() // 特殊bean依然可以使用原生bean方法指定其他模式 bean<SpecialBean>(autowireMode = BeanDefinitionDsl.Autowire.BY_TYPE) }
这个方案的优势是复用性更强,如果你有多个配置类需要相同的规则,只需要引入这个扩展函数即可。
补充说明
这两个方案都完全适配Spring Boot 2.x + Spring Framework 5.x的Kotlin项目,而且不需要修改你的遗留Bean实现(符合你不能用@Component注解的要求)。本质上都是利用Kotlin的DSL和扩展函数特性,减少重复配置代码。
内容的提问来源于stack exchange,提问作者ThomasEdwin
相关产品推荐
相关产品推荐

