Skip to content

Commit fbeb5f1

Browse files
committed
Merge branch '2.5.x'
Closes gh-27636
2 parents 57050fa + 35ea3b2 commit fbeb5f1

File tree

5 files changed

+56
-15
lines changed

5 files changed

+56
-15
lines changed

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,11 @@ public DefaultRepositoryTagsProvider repositoryTagsProvider() {
6464

6565
@Bean
6666
@ConditionalOnMissingBean
67-
public MetricsRepositoryMethodInvocationListener metricsRepositoryMethodInvocationListener(MeterRegistry registry,
68-
RepositoryTagsProvider tagsProvider) {
67+
public MetricsRepositoryMethodInvocationListener metricsRepositoryMethodInvocationListener(
68+
ObjectProvider<MeterRegistry> registry, RepositoryTagsProvider tagsProvider) {
6969
Repository properties = this.properties.getData().getRepository();
70-
return new MetricsRepositoryMethodInvocationListener(registry, tagsProvider, properties.getMetricName(),
71-
properties.getAutotime());
70+
return new MetricsRepositoryMethodInvocationListener(registry::getObject, tagsProvider,
71+
properties.getMetricName(), properties.getAutotime());
7272
}
7373

7474
@Bean

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

+19
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616

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

19+
import io.micrometer.core.instrument.Gauge;
1920
import io.micrometer.core.instrument.MeterRegistry;
21+
import io.micrometer.core.instrument.binder.MeterBinder;
2022
import org.junit.jupiter.api.Test;
2123

2224
import org.springframework.boot.actuate.autoconfigure.metrics.data.city.CityRepository;
@@ -28,6 +30,7 @@
2830
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
2931
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
3032
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
33+
import org.springframework.context.annotation.Bean;
3134
import org.springframework.context.annotation.Configuration;
3235

3336
import static org.assertj.core.api.Assertions.assertThat;
@@ -55,10 +58,26 @@ void repositoryMethodCallRecordsMetrics() {
5558
});
5659
}
5760

61+
@Test
62+
void doesNotPreventMeterBindersFromDependingUponSpringDataRepositories() {
63+
this.contextRunner.withUserConfiguration(SpringDataRepositoryMeterBinderConfiguration.class)
64+
.run((context) -> assertThat(context).hasNotFailed());
65+
}
66+
5867
@Configuration(proxyBeanMethods = false)
5968
@AutoConfigurationPackage
6069
static class TestConfig {
6170

6271
}
6372

73+
@Configuration(proxyBeanMethods = false)
74+
static class SpringDataRepositoryMeterBinderConfiguration {
75+
76+
@Bean
77+
MeterBinder meterBinder(CityRepository repository) {
78+
return (registry) -> Gauge.builder("city.count", repository::count);
79+
}
80+
81+
}
82+
6483
}

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

+8-5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.util.Collection;
2020
import java.util.Collections;
21+
import java.util.function.Supplier;
2122

2223
import io.micrometer.core.annotation.Timed;
2324
import io.micrometer.core.instrument.Meter;
@@ -28,6 +29,7 @@
2829
import io.micrometer.core.instrument.distribution.HistogramSnapshot;
2930
import org.junit.jupiter.api.Test;
3031

32+
import org.springframework.beans.factory.ObjectFactory;
3133
import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun;
3234
import org.springframework.boot.actuate.metrics.AutoTimer;
3335
import org.springframework.boot.actuate.metrics.data.DefaultRepositoryTagsProvider;
@@ -180,17 +182,18 @@ MeterBinder meterBinder() {
180182
static class MetricsRepositoryMethodInvocationListenerConfiguration {
181183

182184
@Bean
183-
MetricsRepositoryMethodInvocationListener metricsRepositoryMethodInvocationListener(MeterRegistry registry,
184-
RepositoryTagsProvider tagsProvider) {
185-
return new TestMetricsRepositoryMethodInvocationListener(registry, tagsProvider);
185+
MetricsRepositoryMethodInvocationListener metricsRepositoryMethodInvocationListener(
186+
ObjectFactory<MeterRegistry> registry, RepositoryTagsProvider tagsProvider) {
187+
return new TestMetricsRepositoryMethodInvocationListener(registry::getObject, tagsProvider);
186188
}
187189

188190
}
189191

190192
static class TestMetricsRepositoryMethodInvocationListener extends MetricsRepositoryMethodInvocationListener {
191193

192-
TestMetricsRepositoryMethodInvocationListener(MeterRegistry registry, RepositoryTagsProvider tagsProvider) {
193-
super(registry, tagsProvider, "test", AutoTimer.DISABLED);
194+
TestMetricsRepositoryMethodInvocationListener(Supplier<MeterRegistry> registrySupplier,
195+
RepositoryTagsProvider tagsProvider) {
196+
super(registrySupplier, tagsProvider, "test", AutoTimer.DISABLED);
194197
}
195198

196199
}

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

+23-4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.util.Set;
2020
import java.util.concurrent.TimeUnit;
21+
import java.util.function.Supplier;
2122

2223
import io.micrometer.core.annotation.Timed;
2324
import io.micrometer.core.instrument.MeterRegistry;
@@ -26,6 +27,7 @@
2627
import org.springframework.boot.actuate.metrics.AutoTimer;
2728
import org.springframework.boot.actuate.metrics.annotation.TimedAnnotations;
2829
import org.springframework.data.repository.core.support.RepositoryMethodInvocationListener;
30+
import org.springframework.util.function.SingletonSupplier;
2931

3032
/**
3133
* Intercepts Spring Data {@code Repository} invocations and records metrics about
@@ -36,7 +38,7 @@
3638
*/
3739
public class MetricsRepositoryMethodInvocationListener implements RepositoryMethodInvocationListener {
3840

39-
private final MeterRegistry registry;
41+
private final SingletonSupplier<MeterRegistry> registrySupplier;
4042

4143
private final RepositoryTagsProvider tagsProvider;
4244

@@ -50,10 +52,27 @@ public class MetricsRepositoryMethodInvocationListener implements RepositoryMeth
5052
* @param tagsProvider provider for metrics tags
5153
* @param metricName name of the metric to record
5254
* @param autoTimer the auto-timers to apply or {@code null} to disable auto-timing
55+
* @deprecated since 2.5.4 for removal in 2.7.0 in favor of
56+
* {@link #MetricsRepositoryMethodInvocationListener(Supplier, RepositoryTagsProvider, String, AutoTimer)}
5357
*/
58+
@Deprecated
5459
public MetricsRepositoryMethodInvocationListener(MeterRegistry registry, RepositoryTagsProvider tagsProvider,
5560
String metricName, AutoTimer autoTimer) {
56-
this.registry = registry;
61+
this(SingletonSupplier.of(registry), tagsProvider, metricName, autoTimer);
62+
}
63+
64+
/**
65+
* Create a new {@code MetricsRepositoryMethodInvocationListener}.
66+
* @param registrySupplier a supplier for the registry to which metrics are recorded
67+
* @param tagsProvider provider for metrics tags
68+
* @param metricName name of the metric to record
69+
* @param autoTimer the auto-timers to apply or {@code null} to disable auto-timing
70+
* @since 2.5.4
71+
*/
72+
public MetricsRepositoryMethodInvocationListener(Supplier<MeterRegistry> registrySupplier,
73+
RepositoryTagsProvider tagsProvider, String metricName, AutoTimer autoTimer) {
74+
this.registrySupplier = (registrySupplier instanceof SingletonSupplier)
75+
? (SingletonSupplier<MeterRegistry>) registrySupplier : SingletonSupplier.of(registrySupplier);
5776
this.tagsProvider = tagsProvider;
5877
this.metricName = metricName;
5978
this.autoTimer = (autoTimer != null) ? autoTimer : AutoTimer.DISABLED;
@@ -64,8 +83,8 @@ public void afterInvocation(RepositoryMethodInvocation invocation) {
6483
Set<Timed> annotations = TimedAnnotations.get(invocation.getMethod(), invocation.getRepositoryInterface());
6584
Iterable<Tag> tags = this.tagsProvider.repositoryTags(invocation);
6685
long duration = invocation.getDuration(TimeUnit.NANOSECONDS);
67-
AutoTimer.apply(this.autoTimer, this.metricName, annotations,
68-
(builder) -> builder.tags(tags).register(this.registry).record(duration, TimeUnit.NANOSECONDS));
86+
AutoTimer.apply(this.autoTimer, this.metricName, annotations, (builder) -> builder.tags(tags)
87+
.register(this.registrySupplier.get()).record(duration, TimeUnit.NANOSECONDS));
6988
}
7089

7190
}

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,13 @@ class MetricsRepositoryMethodInvocationListenerTests {
5353
void setup() {
5454
MockClock clock = new MockClock();
5555
this.registry = new SimpleMeterRegistry(SimpleConfig.DEFAULT, clock);
56-
this.listener = new MetricsRepositoryMethodInvocationListener(this.registry,
56+
this.listener = new MetricsRepositoryMethodInvocationListener(() -> this.registry,
5757
new DefaultRepositoryTagsProvider(), REQUEST_METRICS_NAME, AutoTimer.ENABLED);
5858
}
5959

6060
@Test
6161
void afterInvocationWhenNoTimerAnnotationsAndNoAutoTimerDoesNothing() {
62-
this.listener = new MetricsRepositoryMethodInvocationListener(this.registry,
62+
this.listener = new MetricsRepositoryMethodInvocationListener(() -> this.registry,
6363
new DefaultRepositoryTagsProvider(), REQUEST_METRICS_NAME, null);
6464
this.listener.afterInvocation(createInvocation(NoAnnotationsRepository.class));
6565
assertThat(this.registry.find(REQUEST_METRICS_NAME).timers()).isEmpty();

0 commit comments

Comments
 (0)