Avoid eager initialization when configuring Data repository metrics
Fixes gh-26630
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.metrics.data;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.boot.actuate.metrics.data.MetricsRepositoryMethodInvocationListener;
|
||||
@@ -33,8 +35,9 @@ class MetricsRepositoryMethodInvocationListenerBeanPostProcessor implements Bean
|
||||
|
||||
private final RepositoryFactoryCustomizer customizer;
|
||||
|
||||
MetricsRepositoryMethodInvocationListenerBeanPostProcessor(MetricsRepositoryMethodInvocationListener listener) {
|
||||
this.customizer = (repositoryFactory) -> repositoryFactory.addInvocationListener(listener);
|
||||
MetricsRepositoryMethodInvocationListenerBeanPostProcessor(
|
||||
Supplier<MetricsRepositoryMethodInvocationListener> listener) {
|
||||
this.customizer = new MetricsRepositoryFactoryCustomizer(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -45,4 +48,25 @@ class MetricsRepositoryMethodInvocationListenerBeanPostProcessor implements Bean
|
||||
return bean;
|
||||
}
|
||||
|
||||
private static final class MetricsRepositoryFactoryCustomizer implements RepositoryFactoryCustomizer {
|
||||
|
||||
private final Supplier<MetricsRepositoryMethodInvocationListener> listenerSupplier;
|
||||
|
||||
private volatile MetricsRepositoryMethodInvocationListener listener;
|
||||
|
||||
private MetricsRepositoryFactoryCustomizer(
|
||||
Supplier<MetricsRepositoryMethodInvocationListener> listenerSupplier) {
|
||||
this.listenerSupplier = listenerSupplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customize(RepositoryFactorySupport repositoryFactory) {
|
||||
if (this.listener == null) {
|
||||
this.listener = this.listenerSupplier.get();
|
||||
}
|
||||
repositoryFactory.addInvocationListener(this.listener);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.boot.actuate.autoconfigure.metrics.data;
|
||||
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
|
||||
@@ -72,9 +73,9 @@ public class RepositoryMetricsAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public static MetricsRepositoryMethodInvocationListenerBeanPostProcessor metricsRepositoryMethodInvocationListenerBeanPostProcessor(
|
||||
MetricsRepositoryMethodInvocationListener metricsRepositoryMethodInvocationListener) {
|
||||
ObjectProvider<MetricsRepositoryMethodInvocationListener> metricsRepositoryMethodInvocationListener) {
|
||||
return new MetricsRepositoryMethodInvocationListenerBeanPostProcessor(
|
||||
metricsRepositoryMethodInvocationListener);
|
||||
metricsRepositoryMethodInvocationListener::getObject);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ class MetricsRepositoryMethodInvocationListenerBeanPostProcessorTests {
|
||||
private MetricsRepositoryMethodInvocationListener listener = mock(MetricsRepositoryMethodInvocationListener.class);
|
||||
|
||||
private MetricsRepositoryMethodInvocationListenerBeanPostProcessor postProcessor = new MetricsRepositoryMethodInvocationListenerBeanPostProcessor(
|
||||
this.listener);
|
||||
() -> this.listener);
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("rawtypes")
|
||||
|
||||
@@ -24,6 +24,7 @@ import io.micrometer.core.instrument.Meter;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import io.micrometer.core.instrument.Timer;
|
||||
import io.micrometer.core.instrument.binder.MeterBinder;
|
||||
import io.micrometer.core.instrument.distribution.HistogramSnapshot;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -125,6 +126,13 @@ class RepositoryMetricsAutoConfigurationTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void doesNotTriggerEarlyInitializationThatPreventsMeterBindersFromBindingMeters() {
|
||||
this.contextRunner.withUserConfiguration(MeterBinderConfiguration.class)
|
||||
.run((context) -> assertThat(context.getBean(MeterRegistry.class).find("binder.test").counter())
|
||||
.isNotNull());
|
||||
}
|
||||
|
||||
private MeterRegistry getInitializedMeterRegistry(AssertableApplicationContext context,
|
||||
Class<?> repositoryInterface) {
|
||||
MetricsRepositoryMethodInvocationListener listener = context
|
||||
@@ -158,6 +166,16 @@ class RepositoryMetricsAutoConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class MeterBinderConfiguration {
|
||||
|
||||
@Bean
|
||||
MeterBinder meterBinder() {
|
||||
return (registry) -> registry.counter("binder.test");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class MetricsRepositoryMethodInvocationListenerConfiguration {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user