Polish "Stop closing parent's MeterRegistry beans when child context closes"

See gh-48319
This commit is contained in:
Andy Wilkinson
2025-11-28 09:26:29 +00:00
parent c89576d14d
commit e65baba3a7
2 changed files with 27 additions and 17 deletions
@@ -70,8 +70,8 @@ public class MetricsAutoConfiguration {
}
@Bean
MeterRegistryCloser meterRegistryCloser() {
return new MeterRegistryCloser();
MeterRegistryCloser meterRegistryCloser(ApplicationContext context) {
return new MeterRegistryCloser(context);
}
/**
@@ -80,12 +80,19 @@ public class MetricsAutoConfiguration {
*/
static class MeterRegistryCloser implements ApplicationListener<ContextClosedEvent> {
private final ApplicationContext context;
private final Iterable<MeterRegistry> meterRegistries;
MeterRegistryCloser(ApplicationContext context) {
this.meterRegistries = context.getBeansOfType(MeterRegistry.class).values();
this.context = context;
}
@Override
public void onApplicationEvent(ContextClosedEvent event) {
if (event.getApplicationContext().getParent() == null) {
for (MeterRegistry meterRegistry : event.getApplicationContext()
.getBeansOfType(MeterRegistry.class)
.values()) {
if (this.context.equals(event.getApplicationContext())) {
for (MeterRegistry meterRegistry : this.meterRegistries) {
if (!meterRegistry.isClosed()) {
meterRegistry.close();
}
@@ -30,7 +30,6 @@ import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.test.util.ReflectionTestUtils;
@@ -92,17 +91,21 @@ class MetricsAutoConfigurationTests {
}
@Test
void meterRegistryCloserShouldNotCloseOnNonRootContextClosing() {
this.contextRunner.withUserConfiguration(MeterRegistryConfiguration.class).run((context) -> {
MeterRegistry meterRegistry = context.getBean(MeterRegistry.class);
GenericApplicationContext childContext = new GenericApplicationContext();
childContext.setParent(context);
childContext.refresh();
childContext.close();
assertThat(meterRegistry.isClosed()).isFalse();
context.close();
assertThat(meterRegistry.isClosed()).isTrue();
void meterRegistryCloserShouldOnlyCloseRegistriesBelongingToContextBeingClosed() {
MeterRegistry parentMeterRegistry = new SimpleMeterRegistry();
MeterRegistry childMeterRegistry = new SimpleMeterRegistry();
this.contextRunner.withBean(MeterRegistry.class, () -> parentMeterRegistry).run((parent) -> {
this.contextRunner.withBean(MeterRegistry.class, () -> childMeterRegistry)
.withParent(parent)
.run((child) -> {
assertThat(childMeterRegistry.isClosed()).isFalse();
assertThat(parentMeterRegistry.isClosed()).isFalse();
});
assertThat(childMeterRegistry.isClosed()).isTrue();
assertThat(parentMeterRegistry.isClosed()).isFalse();
});
assertThat(childMeterRegistry.isClosed()).isTrue();
assertThat(parentMeterRegistry.isClosed()).isTrue();
}
@Configuration(proxyBeanMethods = false)