Merge pull request #50235 from kwondh5217

* fix/remove-meter-registry-from-global-on-context-close:
  Remove MeterRegistry from global registry on context close

Closes gh-50235
This commit is contained in:
Stéphane Nicoll
2026-05-04 08:21:55 +02:00
2 changed files with 38 additions and 3 deletions
@@ -19,6 +19,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics;
import io.micrometer.core.annotation.Timed;
import io.micrometer.core.instrument.Clock;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.binder.MeterBinder;
import io.micrometer.core.instrument.config.MeterFilter;
@@ -70,8 +71,8 @@ public class MetricsAutoConfiguration {
}
@Bean
MeterRegistryCloser meterRegistryCloser(ApplicationContext context) {
return new MeterRegistryCloser(context);
MeterRegistryCloser meterRegistryCloser(ApplicationContext context, MetricsProperties properties) {
return new MeterRegistryCloser(context, properties.isUseGlobalRegistry());
}
/**
@@ -84,15 +85,21 @@ public class MetricsAutoConfiguration {
private final Iterable<MeterRegistry> meterRegistries;
MeterRegistryCloser(ApplicationContext context) {
private final boolean useGlobalRegistry;
MeterRegistryCloser(ApplicationContext context, boolean useGlobalRegistry) {
this.meterRegistries = context.getBeansOfType(MeterRegistry.class).values();
this.context = context;
this.useGlobalRegistry = useGlobalRegistry;
}
@Override
public void onApplicationEvent(ContextClosedEvent event) {
if (this.context.equals(event.getApplicationContext())) {
for (MeterRegistry meterRegistry : this.meterRegistries) {
if (this.useGlobalRegistry) {
Metrics.globalRegistry.remove(meterRegistry);
}
if (!meterRegistry.isClosed()) {
meterRegistry.close();
}
@@ -19,6 +19,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics;
import io.micrometer.core.instrument.Clock;
import io.micrometer.core.instrument.Meter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.binder.MeterBinder;
import io.micrometer.core.instrument.config.MeterFilter;
import io.micrometer.core.instrument.config.MeterFilterReply;
@@ -90,6 +91,33 @@ class MetricsAutoConfigurationTests {
});
}
@Test
void meterRegistryCloserShouldRemoveRegistryFromGlobalRegistryOnShutdown() {
this.contextRunner.withUserConfiguration(MeterRegistryConfiguration.class).run((context) -> {
MeterRegistry meterRegistry = context.getBean(MeterRegistry.class);
assertThat(Metrics.globalRegistry.getRegistries()).contains(meterRegistry);
context.close();
assertThat(Metrics.globalRegistry.getRegistries()).doesNotContain(meterRegistry);
});
}
@Test
void meterRegistryCloserShouldNotRemoveRegistryFromGlobalRegistryWhenUseGlobalRegistryIsFalse() {
this.contextRunner.withUserConfiguration(MeterRegistryConfiguration.class)
.withPropertyValues("management.metrics.use-global-registry=false")
.run((context) -> {
MeterRegistry meterRegistry = context.getBean(MeterRegistry.class);
Metrics.globalRegistry.add(meterRegistry);
try {
context.close();
assertThat(Metrics.globalRegistry.getRegistries()).contains(meterRegistry);
}
finally {
Metrics.globalRegistry.remove(meterRegistry);
}
});
}
@Test
void meterRegistryCloserShouldOnlyCloseRegistriesBelongingToContextBeingClosed() {
MeterRegistry parentMeterRegistry = new SimpleMeterRegistry();