diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryPostProcessor.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryPostProcessor.java index 801a65f7e601..adcf0ccc8b2e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryPostProcessor.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterRegistryPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2024 the original author or authors. + * Copyright 2012-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,6 +39,7 @@ * @author Jon Schneider * @author Phillip Webb * @author Andy Wilkinson + * @author Yanming Zhou */ class MeterRegistryPostProcessor implements BeanPostProcessor, SmartInitializingSingleton { @@ -116,7 +117,8 @@ private void applyFilters(MeterRegistry meterRegistry) { } private void addToGlobalRegistryIfNecessary(MeterRegistry meterRegistry) { - if (this.properties.getObject().isUseGlobalRegistry() && !isGlobalRegistry(meterRegistry)) { + if (this.properties.getObject().isUseGlobalRegistry() && !isGlobalRegistry(meterRegistry) + && !isAutoConfiguredComposite(meterRegistry)) { Metrics.addRegistry(meterRegistry); } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationMeterRegistryPostProcessorIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationMeterRegistryPostProcessorIntegrationTests.java index ef1558f04349..c18c1f03f1ac 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationMeterRegistryPostProcessorIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsAutoConfigurationMeterRegistryPostProcessorIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.LoggerContext; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.binder.MeterBinder; import io.micrometer.core.instrument.composite.CompositeMeterRegistry; import org.junit.jupiter.api.Test; @@ -45,6 +46,7 @@ * {@link MetricsAutoConfiguration}. * * @author Jon Schneider + * @author Yanming Zhou */ class MetricsAutoConfigurationMeterRegistryPostProcessorIntegrationTests { @@ -104,6 +106,20 @@ void counterIsIncrementedOncePerEventWithCompositeMeterRegistry() { }); } + @Test + void excludeAutoConfiguredCompositeFromGlobalRegistry() { + this.contextRunner.withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class)) + .withPropertyValues("management.metrics.use-global-registry=true") + .run((context) -> { + assertThat(context).hasSingleBean(AutoConfiguredCompositeMeterRegistry.class); + assertThat(Metrics.globalRegistry.getRegistries()).isNotEmpty(); + assertThat(Metrics.globalRegistry.getRegistries() + .stream() + .filter(AutoConfiguredCompositeMeterRegistry.class::isInstance) + .findAny()).isEmpty(); + }); + } + @Configuration(proxyBeanMethods = false) static class TestConfiguration {