I'm using a MeterBinder as suggested by the docs to register a gauge. While this worked perfectly fine on Spring Boot 2.4.9 it results in a bean definition cycle with 2.5.3,

Minimal project to reproduce the issue: https://github.com/joshiste/issues/tree/boot-meterbinder

the dependencies of some of the beans in the application context form a cycle:

┌─────┐
|  service defined in com.example.demo.DemoApplication
↑     ↓
|  usersRepository defined in com.example.demo.UsersRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration
↑     ↓
|  metricsRepositoryMethodInvocationListener defined in class path resource [org/springframework/boot/actuate/autoconfigure/metrics/data/RepositoryMetricsAutoConfiguration.class]
↑     ↓
|  simpleMeterRegistry defined in class path resource [org/springframework/boot/actuate/autoconfigure/metrics/export/simple/SimpleMetricsExportAutoConfiguration.class]
↑     ↓
|  userMetrics defined in com.example.demo.DemoApplication
└─────┘

My Bean definitions:

   @Bean
    UserService service(UsersRepository repsitory) {
        return new UserService(repsitory);
    }

    @Bean
    MeterBinder userMetrics(UserService userService) {
        return registry -> Gauge.builder("user.cout", userService::count);
    }
 ```



**Comment From: wilkinsona**

Thanks for the report, @joshiste. The cycle is due to the introduction of [metrics for Spring Data repositories](https://github.com/spring-projects/spring-boot/issues/22217). You can break it in your own code by making `UserService` lazy when you inject it into `userMetrics`:

```java
@Bean
MeterBinder userMetrics(@Lazy UserService userService) {
    return registry -> Gauge.builder("user.cout", userService::count);
}

We'll have to see if there's something we can do in Spring Boot to make this unnecessary. If there isn't, we can at least update the documentation with some additional guidance.

Comment From: wilkinsona

We can break the cycle in Boot by annotating the MeterRegistry that's injected into the metricsRepositoryMethodInvocationListener @Bean method @Lazy. Another option may be to use ObjectFactory to defer the retrieval of the bean but this would require changes to MetricsRepositoryMethodInvocationListener to overload the constructor. I'd like to discuss the options with the team.

Comment From: philwebb

We discussed this today and we're going to change the MetricsRepositoryMethodInvocationListener to accept a Supplier. We'll deprecate the existing constructor and call the new one with a SingletonSupplier.