Skip to content

Commit 7a70508

Browse files
committed
Avoid eager initialization when configuring Data repository metrics
Fixes gh-26630
1 parent 3a28aee commit 7a70508

File tree

4 files changed

+48
-5
lines changed

4 files changed

+48
-5
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/data/MetricsRepositoryMethodInvocationListenerBeanPostProcessor.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure.metrics.data;
1818

19+
import java.util.function.Supplier;
20+
1921
import org.springframework.beans.BeansException;
2022
import org.springframework.beans.factory.config.BeanPostProcessor;
2123
import org.springframework.boot.actuate.metrics.data.MetricsRepositoryMethodInvocationListener;
@@ -33,8 +35,9 @@ class MetricsRepositoryMethodInvocationListenerBeanPostProcessor implements Bean
3335

3436
private final RepositoryFactoryCustomizer customizer;
3537

36-
MetricsRepositoryMethodInvocationListenerBeanPostProcessor(MetricsRepositoryMethodInvocationListener listener) {
37-
this.customizer = (repositoryFactory) -> repositoryFactory.addInvocationListener(listener);
38+
MetricsRepositoryMethodInvocationListenerBeanPostProcessor(
39+
Supplier<MetricsRepositoryMethodInvocationListener> listener) {
40+
this.customizer = new MetricsRepositoryFactoryCustomizer(listener);
3841
}
3942

4043
@Override
@@ -45,4 +48,25 @@ public Object postProcessBeforeInitialization(Object bean, String beanName) thro
4548
return bean;
4649
}
4750

51+
private static final class MetricsRepositoryFactoryCustomizer implements RepositoryFactoryCustomizer {
52+
53+
private final Supplier<MetricsRepositoryMethodInvocationListener> listenerSupplier;
54+
55+
private volatile MetricsRepositoryMethodInvocationListener listener;
56+
57+
private MetricsRepositoryFactoryCustomizer(
58+
Supplier<MetricsRepositoryMethodInvocationListener> listenerSupplier) {
59+
this.listenerSupplier = listenerSupplier;
60+
}
61+
62+
@Override
63+
public void customize(RepositoryFactorySupport repositoryFactory) {
64+
if (this.listener == null) {
65+
this.listener = this.listenerSupplier.get();
66+
}
67+
repositoryFactory.addInvocationListener(this.listener);
68+
}
69+
70+
}
71+
4872
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/data/RepositoryMetricsAutoConfiguration.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import io.micrometer.core.instrument.MeterRegistry;
2020

21+
import org.springframework.beans.factory.ObjectProvider;
2122
import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration;
2223
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
2324
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
@@ -72,9 +73,9 @@ public MetricsRepositoryMethodInvocationListener metricsRepositoryMethodInvocati
7273

7374
@Bean
7475
public static MetricsRepositoryMethodInvocationListenerBeanPostProcessor metricsRepositoryMethodInvocationListenerBeanPostProcessor(
75-
MetricsRepositoryMethodInvocationListener metricsRepositoryMethodInvocationListener) {
76+
ObjectProvider<MetricsRepositoryMethodInvocationListener> metricsRepositoryMethodInvocationListener) {
7677
return new MetricsRepositoryMethodInvocationListenerBeanPostProcessor(
77-
metricsRepositoryMethodInvocationListener);
78+
metricsRepositoryMethodInvocationListener::getObject);
7879
}
7980

8081
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/data/MetricsRepositoryMethodInvocationListenerBeanPostProcessorTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class MetricsRepositoryMethodInvocationListenerBeanPostProcessorTests {
3838
private MetricsRepositoryMethodInvocationListener listener = mock(MetricsRepositoryMethodInvocationListener.class);
3939

4040
private MetricsRepositoryMethodInvocationListenerBeanPostProcessor postProcessor = new MetricsRepositoryMethodInvocationListenerBeanPostProcessor(
41-
this.listener);
41+
() -> this.listener);
4242

4343
@Test
4444
@SuppressWarnings("rawtypes")

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/data/RepositoryMetricsAutoConfigurationTests.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import io.micrometer.core.instrument.MeterRegistry;
2525
import io.micrometer.core.instrument.Tag;
2626
import io.micrometer.core.instrument.Timer;
27+
import io.micrometer.core.instrument.binder.MeterBinder;
2728
import io.micrometer.core.instrument.distribution.HistogramSnapshot;
2829
import org.junit.jupiter.api.Test;
2930

@@ -125,6 +126,13 @@ void timerWorksWithTimedAnnotationsWhenAutoTimeRequestsIsFalse() {
125126
});
126127
}
127128

129+
@Test
130+
void doesNotTriggerEarlyInitializationThatPreventsMeterBindersFromBindingMeters() {
131+
this.contextRunner.withUserConfiguration(MeterBinderConfiguration.class)
132+
.run((context) -> assertThat(context.getBean(MeterRegistry.class).find("binder.test").counter())
133+
.isNotNull());
134+
}
135+
128136
private MeterRegistry getInitializedMeterRegistry(AssertableApplicationContext context,
129137
Class<?> repositoryInterface) {
130138
MetricsRepositoryMethodInvocationListener listener = context
@@ -158,6 +166,16 @@ public Iterable<Tag> repositoryTags(RepositoryMethodInvocation invocation) {
158166

159167
}
160168

169+
@Configuration(proxyBeanMethods = false)
170+
static class MeterBinderConfiguration {
171+
172+
@Bean
173+
MeterBinder meterBinder() {
174+
return (registry) -> registry.counter("binder.test");
175+
}
176+
177+
}
178+
161179
@Configuration(proxyBeanMethods = false)
162180
static class MetricsRepositoryMethodInvocationListenerConfiguration {
163181

0 commit comments

Comments
 (0)