I have a starter module which expose a marker interface along with some 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
In another module, I have an auto configuration which depends on the AwesomeRepo
to instantiate the AwesomeApplicationService
@Configuration(proxyBeanMethods = false)
class AwesomeAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnBean(AwesomeRepo::class)
fun awesomeAppService(awesomeRepo: AwesomeRepo) =
AwesomeApplicationService(awesomeRepo)
I import both autoconfigure starters in a root project.
I observe:
AwesomeApplicationService
cannot be instantiated because AwesomeRepo
bean cannot be foundWhen enabling debug through 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)
to AwesomePersistenceAutoConfiguration
and @AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)
to AwesomeAutoConfiguration
. It did not change the issue@ConditionOnBean(AwesomeRepo::class)
, the AwesomeApplicationService
is correctly instantiated with the repository and everything is fine.Why does the @ConditionOnBean(AwesomeRepo::class)
does not detect the AwesomeRepo
bean?
EDIT: After more trials and errors, it seems order was causing the issue, applying accepted answer worked. If someone needs to go further there is a baseline of code illustrating the issue here: https://github.com/Nimamoh/spring-autoconfigurations-conditionalonbean-with-a-repository (accepted answer is on snic-answer
branch)
AwesomeAutoConfiguration
should be ordered after AwesomePersistenceAutoConfiguration
so that the bean definitions for the repositories are processed before the condition kicks in.
There is a note in @ConditionalOnBean
about this specifically:
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.
You can use @AutoConfigureAfter(AwesomePersistenceAutoConfiguration.class)
on AwesomeAutoConfiguration
to order things properly.