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)

我在根项目中导入了两个自动配置启动器。

我观察到:

通过debug=true启用调试时:

AwesomeAutoConfiguration #awesomeAppService:
      Did not match:
         - @ConditionalOnBean (types: *****.AwesomeRepo; SearchStrategy: all) did not find any beans of type *******.AwesomeRepo(OnBeanCondition)

为什么 @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) 来正确订购东西。