Browse Source

Support @Value meta-annotations and expose MergedAnnotations on PreferredConstructor parameters.

We now support composed annotation that are annotated with `@Value`. we also expose MergedAnnotations through PreferredConstructor.Parameter for further use by store modules that want to inspect constructor argument annotations.

Closes: #2332
Original Pull Request: #2333
pull/2344/head
Mark Paluch 5 years ago committed by Christoph Strobl
parent
commit
79ed0a75c7
  1. 25
      src/main/java/org/springframework/data/mapping/PreferredConstructor.java
  2. 30
      src/test/java/org/springframework/data/mapping/PreferredConstructorDiscovererUnitTests.java

25
src/main/java/org/springframework/data/mapping/PreferredConstructor.java

@ -23,6 +23,7 @@ import java.util.Map; @@ -23,6 +23,7 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.util.Lazy;
import org.springframework.data.util.TypeInformation;
@ -175,6 +176,7 @@ public class PreferredConstructor<T, P extends PersistentProperty<P>> { @@ -175,6 +176,7 @@ public class PreferredConstructor<T, P extends PersistentProperty<P>> {
private final @Nullable String name;
private final TypeInformation<T> type;
private final MergedAnnotations annotations;
private final String key;
private final @Nullable PersistentEntity<T, P> entity;
@ -199,7 +201,8 @@ public class PreferredConstructor<T, P extends PersistentProperty<P>> { @@ -199,7 +201,8 @@ public class PreferredConstructor<T, P extends PersistentProperty<P>> {
this.name = name;
this.type = type;
this.key = getValue(annotations);
this.annotations = MergedAnnotations.from(annotations);
this.key = getValue(this.annotations);
this.entity = entity;
this.enclosingClassCache = Lazy.of(() -> {
@ -216,12 +219,12 @@ public class PreferredConstructor<T, P extends PersistentProperty<P>> { @@ -216,12 +219,12 @@ public class PreferredConstructor<T, P extends PersistentProperty<P>> {
}
@Nullable
private static String getValue(Annotation[] annotations) {
private static String getValue(MergedAnnotations annotations) {
return Arrays.stream(annotations)//
.filter(it -> it.annotationType() == Value.class)//
.findFirst().map(it -> ((Value) it).value())//
.filter(StringUtils::hasText).orElse(null);
return annotations.get(Value.class) //
.getValue("value", String.class) //
.filter(StringUtils::hasText) //
.orElse(null);
}
/**
@ -243,6 +246,16 @@ public class PreferredConstructor<T, P extends PersistentProperty<P>> { @@ -243,6 +246,16 @@ public class PreferredConstructor<T, P extends PersistentProperty<P>> {
return type;
}
/**
* Merged annotations that this parameter is annotated with.
*
* @return
* @since 2.5
*/
public MergedAnnotations getAnnotations() {
return annotations;
}
/**
* Returns the raw resolved type of the parameter.
*

30
src/test/java/org/springframework/data/mapping/PreferredConstructorDiscovererUnitTests.java

@ -17,9 +17,15 @@ package org.springframework.data.mapping; @@ -17,9 +17,15 @@ package org.springframework.data.mapping;
import static org.assertj.core.api.Assertions.*;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Iterator;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.mapping.PreferredConstructor.Parameter;
import org.springframework.data.mapping.PreferredConstructorDiscovererUnitTests.Outer.Inner;
@ -135,6 +141,16 @@ class PreferredConstructorDiscovererUnitTests<P extends PersistentProperty<P>> { @@ -135,6 +141,16 @@ class PreferredConstructorDiscovererUnitTests<P extends PersistentProperty<P>> {
});
}
@Test // GH-2332
void detectsMetaAnnotatedValueAnnotation() {
assertThat(PreferredConstructorDiscoverer.discover(ClassWithMetaAnnotatedParameter.class)).satisfies(ctor -> {
assertThat(ctor.getParameters().get(0).getSpelExpression()).isEqualTo("${hello-world}");
assertThat(ctor.getParameters().get(0).getAnnotations()).isNotNull();
});
}
static class SyntheticConstructor {
@PersistenceConstructor
private SyntheticConstructor(String x) {}
@ -204,4 +220,18 @@ class PreferredConstructorDiscovererUnitTests<P extends PersistentProperty<P>> { @@ -204,4 +220,18 @@ class PreferredConstructorDiscovererUnitTests<P extends PersistentProperty<P>> {
super(value);
}
}
static class ClassWithMetaAnnotatedParameter {
ClassWithMetaAnnotatedParameter(@MyValue String value) {
}
}
@Target({ ElementType.PARAMETER, })
@Retention(RetentionPolicy.RUNTIME)
@Value("${hello-world}")
@interface MyValue {
}
}

Loading…
Cancel
Save