spring-boot
spring-boot copied to clipboard
startupTimeMetrics seems to cause bean dependency cycle when a MeterBinder uses a spring data repository
Spring Boot version: 2.6.7
We seem to be running into an issue similar to https://github.com/spring-projects/spring-boot/issues/27591.
We recently migrated one of our metric sources to use a spring data repository. This seems to cause a bean dependency cycle caused by startupTimeMetrics (See attached bean cycle screenshot).

If needed, I can attempt to provide a minimal reproducer, but I hope the current information is enough.
If needed, I can attempt to provide a minimal reproducer, but I hope the current information is enough.
Yes, please. I have been unable to reproduce the problem from what you have described thus far.
While building the reproducer I noticed that the problem is caused by including spring-cloud-gcp-starter-data-firestore, with plain data-jpa I could not reproduce it as well.
I'll open an issue on that project.
Thanks for letting me know. FWIW the dependency between serviceInstanceRepository and startupTimeMetrics looks a little unusual. If serviceInstanceRepository is a Data Firestore repository, that link is where I'd start looking.
I opened a corresponding issue in the spring cloud gcp project: https://github.com/GoogleCloudPlatform/spring-cloud-gcp/issues/1113
For posterity, the issue is not Firestore-specific, but adding metrics following Spring Boot docs avoids the cycle nicely.
In the reproducer, user implementation of MeterBinder inserted itself in the middle of Micrometer autoconfiguration. It also required a prerequisite service relying on a Spring Data repository, which had to get instantiated first. While instantiating the repository,
org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport brings in org.springframework.data.repository.core.support.EventPublishingRepositoryProxyPostProcessor. Spring Data publishes org.springframework.data.mapping.context.MappingContextEvent when entity type is registered in RepositoryFactoryBeanSupport.afterPropertiesSet(). Because startupTimeMetrics is registered as an ApplicationListener, it has to get instantiated at that point, causing the cycle.
For completeness; here is a reproducer without Firestore: https://github.com/elefeint/FirestoreMetricsReproducer/tree/h2-reproducer