@Autowired基于application.properties中的属性

mas*_*ick 2 java dependency-injection autowired kotlin spring-boot

假设我有几个实现单个接口的Spring组件:

interface Haha
@Component class HahaImpl1: Haha {
   @Autowired lateinit var repo: JpaRepository<Data, Long>
}
@Component class HahaImpl2: Haha

@Service
class Yoyo {
   @Autowired lateinit var haha: Haha
}
Run Code Online (Sandbox Code Playgroud)

如何将正确的依赖项注入我Yoyo可以在application.properties文件内部指定的服务中?

myApp.haha=impl1
Run Code Online (Sandbox Code Playgroud)

我可以创建一个配置,但是随后我将不得不删除@Component我不想要的注释,因为在Haha实现类中,我将注入其他bean(服务,控制器等):

@Configuration
class MyConfiguration {
    @Bean
    @ConditionalOnProperty(name = ["myApp.haha"], havingValue = "impl1", matchIfMissing = true)
    fun config1(): Haha = HahaImpl1()

    @Bean
    @ConditionalOnProperty(name = ["myApp.haha"], havingValue = "impl2")
    fun config2(): Haha = HahaImpl2()
}
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?谢谢。

Tod*_*odd 6

您可以通过将@ConditionalOnProperty移至bean类并@Configuration完全删除该类(或至少删除处理HaHa实例的部分)来解决问题:

interface HaHa

@Component 
@ConditionalOnProperty(name = "myApp.haha", havingValue = "impl1", matchIfMissing = true)
class HahaImpl1: Haha {
    @Autowired 
    lateinit var repo: JpaRepository<Data, Long>
}

@Component 
@ConditionalOnProperty(name = "myApp.haha", havingValue = "impl2")
class HahaImpl2: Haha {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

这样一来,您总是会获得一个实例HaHa,并且仅基于不存在属性的情况。之所以@ConditionalOnProperty可行,是因为它可以出现在Method或Type上