Spring 自动配置,带有@Repository 的@ConditionalOnBean
Spring autoconfigurations, @ConditionalOnBean with a @Repository
我有一个启动模块,它公开了一个标记接口以及一些存储库:
interface AwesomeRepo
...
internal interface FakeRepository: Repository<JPAStub, String>, AwesomeRepo {
fun count(): Long
}
@Entity
class JPAStub(@Id val name: String)
@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(EntityManagerFactory::class)
@AutoConfigureAfter(JpaRepositoriesAutoConfiguration::class)
@EnableJpaRepositories(basePackageClasses = [FakeRepository::class])
@EntityScan(basePackageClasses = [FakeRepository::class])
class AwesomePersistenceAutoConfiguration
在另一个模块中,我有一个自动配置,它依赖于 AwesomeRepo
来实例化 AwesomeApplicationService
@Configuration(proxyBeanMethods = false)
class AwesomeAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnBean(AwesomeRepo::class)
fun awesomeAppService(awesomeRepo: AwesomeRepo) =
AwesomeApplicationService(awesomeRepo)
我在根项目中导入了两个自动配置启动器。
我观察到:
AwesomeApplicationService
无法实例化,因为AwesomeRepo
找不到bean
通过debug=true
启用调试时:
AwesomeAutoConfiguration #awesomeAppService:
Did not match:
- @ConditionalOnBean (types: *****.AwesomeRepo; SearchStrategy: all) did not find any beans of type *******.AwesomeRepo(OnBeanCondition)
- 我尝试将
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
添加到 AwesomePersistenceAutoConfiguration
并将 @AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)
添加到 AwesomeAutoConfiguration
。它没有改变问题
- 当我删除
@ConditionOnBean(AwesomeRepo::class)
时,AwesomeApplicationService
已使用存储库正确实例化,一切正常。
为什么 @ConditionOnBean(AwesomeRepo::class)
没有检测到 AwesomeRepo
bean?
编辑:经过更多的试验和错误,似乎顺序导致了问题,应用接受的答案有效。如果有人需要更进一步,这里有一个代码基线来说明这个问题:https://github.com/Nimamoh/spring-autoconfigurations-conditionalonbean-with-a-repository(接受的答案在 snic-answer
分支上)
AwesomeAutoConfiguration
应该排在 AwesomePersistenceAutoConfiguration
之后,以便在条件开始之前处理存储库的 bean 定义。
@ConditionalOnBean
中有一个注释专门针对此:
The condition can only match the bean definitions that have been processed by the application context so far and, as such, it is strongly recommended to use this condition on auto-configuration classes only. If a candidate bean may be created by another auto-configuration, make sure that the one using this condition runs after.
您可以在 AwesomeAutoConfiguration
上使用 @AutoConfigureAfter(AwesomePersistenceAutoConfiguration.class)
来正确订购东西。
我有一个启动模块,它公开了一个标记接口以及一些存储库:
interface AwesomeRepo
...
internal interface FakeRepository: Repository<JPAStub, String>, AwesomeRepo {
fun count(): Long
}
@Entity
class JPAStub(@Id val name: String)
@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(EntityManagerFactory::class)
@AutoConfigureAfter(JpaRepositoriesAutoConfiguration::class)
@EnableJpaRepositories(basePackageClasses = [FakeRepository::class])
@EntityScan(basePackageClasses = [FakeRepository::class])
class AwesomePersistenceAutoConfiguration
在另一个模块中,我有一个自动配置,它依赖于 AwesomeRepo
来实例化 AwesomeApplicationService
@Configuration(proxyBeanMethods = false)
class AwesomeAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnBean(AwesomeRepo::class)
fun awesomeAppService(awesomeRepo: AwesomeRepo) =
AwesomeApplicationService(awesomeRepo)
我在根项目中导入了两个自动配置启动器。
我观察到:
AwesomeApplicationService
无法实例化,因为AwesomeRepo
找不到bean
通过debug=true
启用调试时:
AwesomeAutoConfiguration #awesomeAppService:
Did not match:
- @ConditionalOnBean (types: *****.AwesomeRepo; SearchStrategy: all) did not find any beans of type *******.AwesomeRepo(OnBeanCondition)
- 我尝试将
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
添加到AwesomePersistenceAutoConfiguration
并将@AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)
添加到AwesomeAutoConfiguration
。它没有改变问题 - 当我删除
@ConditionOnBean(AwesomeRepo::class)
时,AwesomeApplicationService
已使用存储库正确实例化,一切正常。
为什么 @ConditionOnBean(AwesomeRepo::class)
没有检测到 AwesomeRepo
bean?
编辑:经过更多的试验和错误,似乎顺序导致了问题,应用接受的答案有效。如果有人需要更进一步,这里有一个代码基线来说明这个问题:https://github.com/Nimamoh/spring-autoconfigurations-conditionalonbean-with-a-repository(接受的答案在 snic-answer
分支上)
AwesomeAutoConfiguration
应该排在 AwesomePersistenceAutoConfiguration
之后,以便在条件开始之前处理存储库的 bean 定义。
@ConditionalOnBean
中有一个注释专门针对此:
The condition can only match the bean definitions that have been processed by the application context so far and, as such, it is strongly recommended to use this condition on auto-configuration classes only. If a candidate bean may be created by another auto-configuration, make sure that the one using this condition runs after.
您可以在 AwesomeAutoConfiguration
上使用 @AutoConfigureAfter(AwesomePersistenceAutoConfiguration.class)
来正确订购东西。