Skip to content

Commit e66e9ab

Browse files
committed
Add nullability annotations to module/spring-boot-data-commons
See gh-46587
1 parent 481ed5b commit e66e9ab

File tree

9 files changed

+44
-16
lines changed

9 files changed

+44
-16
lines changed

module/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/metrics/DataMetricsProperties.java

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

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

19+
import org.jspecify.annotations.Nullable;
20+
1921
import org.springframework.boot.context.properties.ConfigurationProperties;
2022

2123
/**
@@ -73,7 +75,7 @@ public static class Autotime {
7375
/**
7476
* Percentiles for which additional time series should be published.
7577
*/
76-
private double[] percentiles;
78+
private double @Nullable [] percentiles;
7779

7880
public boolean isEnabled() {
7981
return this.enabled;
@@ -91,11 +93,11 @@ public void setPercentilesHistogram(boolean percentilesHistogram) {
9193
this.percentilesHistogram = percentilesHistogram;
9294
}
9395

94-
public double[] getPercentiles() {
96+
public double @Nullable [] getPercentiles() {
9597
return this.percentiles;
9698
}
9799

98-
public void setPercentiles(double[] percentiles) {
100+
public void setPercentiles(double @Nullable [] percentiles) {
99101
this.percentiles = percentiles;
100102
}
101103

module/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/metrics/MetricsRepositoryMethodInvocationListenerBeanPostProcessor.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
2323
import org.springframework.data.repository.core.support.RepositoryFactoryCustomizer;
2424
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
25+
import org.springframework.util.Assert;
2526
import org.springframework.util.function.SingletonSupplier;
2627

2728
/**
@@ -58,7 +59,9 @@ private MetricsRepositoryFactoryCustomizer(
5859

5960
@Override
6061
public void customize(RepositoryFactorySupport repositoryFactory) {
61-
repositoryFactory.addInvocationListener(this.listenerSupplier.get());
62+
MetricsRepositoryMethodInvocationListener listener = this.listenerSupplier.get();
63+
Assert.state(listener != null, "'listener' must not be null");
64+
repositoryFactory.addInvocationListener(listener);
6265
}
6366

6467
}

module/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/metrics/package-info.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@
1717
/**
1818
* Auto-configuration for Spring Data repository metrics.
1919
*/
20+
@NullMarked
2021
package org.springframework.boot.data.autoconfigure.metrics;
22+
23+
import org.jspecify.annotations.NullMarked;

module/spring-boot-data-commons/src/main/java/org/springframework/boot/data/autoconfigure/web/package-info.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@
1717
/**
1818
* Auto-configuration for Spring Data web.
1919
*/
20+
@NullMarked
2021
package org.springframework.boot.data.autoconfigure.web;
22+
23+
import org.jspecify.annotations.NullMarked;

module/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/AutoTimer.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import io.micrometer.core.annotation.Timed;
2424
import io.micrometer.core.instrument.Timer;
2525
import io.micrometer.core.instrument.Timer.Builder;
26+
import org.jspecify.annotations.Nullable;
2627

2728
import org.springframework.util.CollectionUtils;
2829

@@ -98,7 +99,8 @@ default Timer.Builder builder(Supplier<Timer.Builder> supplier) {
9899
*/
99100
void apply(Timer.Builder builder);
100101

101-
static void apply(AutoTimer autoTimer, String metricName, Set<Timed> annotations, Consumer<Timer.Builder> action) {
102+
static void apply(@Nullable AutoTimer autoTimer, String metricName, Set<Timed> annotations,
103+
Consumer<Timer.Builder> action) {
102104
if (!CollectionUtils.isEmpty(annotations)) {
103105
for (Timed annotation : annotations) {
104106
action.accept(Timer.builder(annotation, metricName));

module/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/DefaultRepositoryTagsProvider.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121

2222
import io.micrometer.core.instrument.Tag;
2323
import io.micrometer.core.instrument.Tags;
24+
import org.jspecify.annotations.Nullable;
2425

2526
import org.springframework.data.repository.core.support.RepositoryMethodInvocationListener.RepositoryMethodInvocation;
27+
import org.springframework.data.repository.core.support.RepositoryMethodInvocationListener.RepositoryMethodInvocationResult;
2628
import org.springframework.data.repository.core.support.RepositoryMethodInvocationListener.RepositoryMethodInvocationResult.State;
2729
import org.springframework.util.StringUtils;
2830

@@ -41,16 +43,20 @@ public Iterable<Tag> repositoryTags(RepositoryMethodInvocation invocation) {
4143
Tags tags = Tags.empty();
4244
tags = and(tags, invocation.getRepositoryInterface(), "repository", this::getSimpleClassName);
4345
tags = and(tags, invocation.getMethod(), "method", Method::getName);
44-
tags = and(tags, invocation.getResult().getState(), "state", State::name);
45-
tags = and(tags, invocation.getResult().getError(), "exception", this::getExceptionName, EXCEPTION_NONE);
46+
RepositoryMethodInvocationResult result = invocation.getResult();
47+
if (result != null) {
48+
tags = and(tags, result.getState(), "state", State::name);
49+
tags = and(tags, result.getError(), "exception", this::getExceptionName, EXCEPTION_NONE);
50+
}
4651
return tags;
4752
}
4853

49-
private <T> Tags and(Tags tags, T instance, String key, Function<T, String> value) {
54+
private <T> Tags and(Tags tags, @Nullable T instance, String key, Function<T, String> value) {
5055
return and(tags, instance, key, value, null);
5156
}
5257

53-
private <T> Tags and(Tags tags, T instance, String key, Function<T, String> value, Tag fallback) {
58+
private <T> Tags and(Tags tags, @Nullable T instance, String key, Function<T, String> value,
59+
@Nullable Tag fallback) {
5460
if (instance != null) {
5561
return tags.and(key, value.apply(instance));
5662
}

module/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/MetricsRepositoryMethodInvocationListener.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323
import io.micrometer.core.annotation.Timed;
2424
import io.micrometer.core.instrument.MeterRegistry;
2525
import io.micrometer.core.instrument.Tag;
26+
import org.jspecify.annotations.Nullable;
2627

2728
import org.springframework.data.repository.core.support.RepositoryMethodInvocationListener;
29+
import org.springframework.util.Assert;
2830
import org.springframework.util.function.SingletonSupplier;
2931

3032
/**
@@ -53,7 +55,7 @@ public class MetricsRepositoryMethodInvocationListener implements RepositoryMeth
5355
* @since 4.0.0
5456
*/
5557
public MetricsRepositoryMethodInvocationListener(Supplier<MeterRegistry> registrySupplier,
56-
RepositoryTagsProvider tagsProvider, String metricName, AutoTimer autoTimer) {
58+
RepositoryTagsProvider tagsProvider, String metricName, @Nullable AutoTimer autoTimer) {
5759
this.registrySupplier = (registrySupplier instanceof SingletonSupplier)
5860
? (SingletonSupplier<MeterRegistry>) registrySupplier : SingletonSupplier.of(registrySupplier);
5961
this.tagsProvider = tagsProvider;
@@ -66,11 +68,14 @@ public void afterInvocation(RepositoryMethodInvocation invocation) {
6668
Set<Timed> annotations = TimedAnnotations.get(invocation.getMethod(), invocation.getRepositoryInterface());
6769
Iterable<Tag> tags = this.tagsProvider.repositoryTags(invocation);
6870
long duration = invocation.getDuration(TimeUnit.NANOSECONDS);
69-
AutoTimer.apply(this.autoTimer, this.metricName, annotations,
70-
(builder) -> builder.description("Duration of repository invocations")
71-
.tags(tags)
72-
.register(this.registrySupplier.get())
73-
.record(duration, TimeUnit.NANOSECONDS));
71+
AutoTimer.apply(this.autoTimer, this.metricName, annotations, (builder) -> {
72+
MeterRegistry registry = this.registrySupplier.get();
73+
Assert.state(registry != null, "'registry' must not be null");
74+
builder.description("Duration of repository invocations")
75+
.tags(tags)
76+
.register(registry)
77+
.record(duration, TimeUnit.NANOSECONDS);
78+
});
7479
}
7580

7681
}

module/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/TimedAnnotations.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.Set;
2424

2525
import io.micrometer.core.annotation.Timed;
26+
import org.jspecify.annotations.Nullable;
2627

2728
import org.springframework.core.annotation.MergedAnnotationCollectors;
2829
import org.springframework.core.annotation.MergedAnnotations;
@@ -56,7 +57,7 @@ public static Set<Timed> get(Method method, Class<?> type) {
5657
return findTimedAnnotations(type);
5758
}
5859

59-
private static Set<Timed> findTimedAnnotations(AnnotatedElement element) {
60+
private static Set<Timed> findTimedAnnotations(@Nullable AnnotatedElement element) {
6061
if (element == null) {
6162
return Collections.emptySet();
6263
}

module/spring-boot-data-commons/src/main/java/org/springframework/boot/data/metrics/package-info.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@
1717
/**
1818
* Spring Data repository metrics.
1919
*/
20+
@NullMarked
2021
package org.springframework.boot.data.metrics;
22+
23+
import org.jspecify.annotations.NullMarked;

0 commit comments

Comments
 (0)