Skip to content

Commit 6bc28c1

Browse files
mp911deschauder
authored andcommitted
Consider annotated methods in AnnotationRevisionMetadata.
We now detect annotated methods. Closes #2569
1 parent 8e241b1 commit 6bc28c1

File tree

3 files changed

+47
-1
lines changed

3 files changed

+47
-1
lines changed

src/main/java/org/springframework/data/history/AnnotationRevisionMetadata.java

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

2525
import org.springframework.data.util.AnnotationDetectionFieldCallback;
26+
import org.springframework.data.util.AnnotationDetectionMethodCallback;
2627
import org.springframework.data.util.Lazy;
2728
import org.springframework.util.Assert;
2829
import org.springframework.util.ReflectionUtils;
@@ -34,6 +35,7 @@
3435
*
3536
* @author Oliver Gierke
3637
* @author Jens Schauder
38+
* @author Mark Paluch
3739
*/
3840
public class AnnotationRevisionMetadata<N extends Number & Comparable<N>> implements RevisionMetadata<N> {
3941

@@ -98,11 +100,19 @@ public <T> T getDelegate() {
98100
return (T) entity;
99101
}
100102

103+
@SuppressWarnings("unchecked")
101104
private static <T> Lazy<Optional<T>> detectAnnotation(Object entity, Class<? extends Annotation> annotationType) {
102105

103106
return Lazy.of(() -> {
104107

105-
var callback = new AnnotationDetectionFieldCallback(annotationType);
108+
AnnotationDetectionMethodCallback<? extends Annotation> methodCallback = new AnnotationDetectionMethodCallback<>(
109+
annotationType);
110+
ReflectionUtils.doWithMethods(entity.getClass(), methodCallback);
111+
if (methodCallback.getMethod() != null) {
112+
return Optional.ofNullable((T) ReflectionUtils.invokeMethod(methodCallback.getRequiredMethod(), entity));
113+
}
114+
115+
AnnotationDetectionFieldCallback callback = new AnnotationDetectionFieldCallback(annotationType);
106116
ReflectionUtils.doWithFields(entity.getClass(), callback);
107117
return Optional.ofNullable(callback.getValue(entity));
108118
});

src/main/java/org/springframework/data/util/AnnotationDetectionMethodCallback.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,15 @@
2121
import org.springframework.core.annotation.AnnotatedElementUtils;
2222
import org.springframework.lang.Nullable;
2323
import org.springframework.util.Assert;
24+
import org.springframework.util.ReflectionUtils;
2425
import org.springframework.util.ReflectionUtils.MethodCallback;
2526

2627
/**
2728
* {@link MethodCallback} to find annotations of a given type.
2829
*
2930
* @author Oliver Gierke
3031
* @author Christoph Strobl
32+
* @author Mark Paluch
3133
*/
3234
public class AnnotationDetectionMethodCallback<A extends Annotation> implements MethodCallback {
3335

@@ -121,6 +123,8 @@ public void doWith(Method method) throws IllegalArgumentException, IllegalAccess
121123
}
122124

123125
this.annotation = foundAnnotation;
126+
127+
ReflectionUtils.makeAccessible(method);
124128
this.foundMethod = method;
125129
}
126130
}

src/test/java/org/springframework/data/history/AnnotationRevisionMetadataUnitTests.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
*
3434
* @author Oliver Gierke
3535
* @author Jens Schauder
36+
* @author Mark Paluch
3637
*/
3738
class AnnotationRevisionMetadataUnitTests {
3839

@@ -83,6 +84,21 @@ void exposesRevisionDateAndInstantForLocalDateTime() {
8384
softly.assertAll();
8485
}
8586

87+
@Test // GH-2569
88+
void exposesRevisionMetadataUsingMethodAccessors() {
89+
90+
SampleWithMethodAnnotations sample = new SampleWithMethodAnnotations();
91+
sample.revisionNumber = 1L;
92+
sample.revisionDate = Instant.now();
93+
94+
RevisionMetadata<Long> metadata = getMetadata(sample);
95+
96+
softly.assertThat(metadata.getRevisionNumber()).hasValue(1L);
97+
softly.assertThat(metadata.getRevisionInstant()).hasValue(sample.revisionDate);
98+
99+
softly.assertAll();
100+
}
101+
86102
@Test // DATACMNS-1251
87103
void exposesRevisionDateAndInstantForInstant() {
88104

@@ -149,6 +165,22 @@ static class Sample {
149165
@Reference LocalDateTime revisionDate;
150166
}
151167

168+
static class SampleWithMethodAnnotations {
169+
170+
Long revisionNumber;
171+
Instant revisionDate;
172+
173+
@Autowired
174+
public Long getRevisionNumber() {
175+
return revisionNumber;
176+
}
177+
178+
@Reference
179+
public Instant getRevisionDate() {
180+
return revisionDate;
181+
}
182+
}
183+
152184
static class SampleWithInstant {
153185

154186
@Autowired Long revisionNumber;

0 commit comments

Comments
 (0)