Support the use of @AliasFor with @PropertyMapping
Previously, when @AliasFor was used, the value of the mapped property would be incorrect as the value of the canonical attribute would be used, rather than the value of the alias. This commit updates AnnotationsPropertySource to use a merged annotation as the source of attribute values, thereby ensuring that any aliased attributes are configured correctly. Closes gh-5821
This commit is contained in:
parent
f468aff47f
commit
41ddda4a15
|
@ -18,12 +18,15 @@ package org.springframework.boot.test.autoconfigure.properties;
|
|||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.env.EnumerablePropertySource;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
@ -55,28 +58,39 @@ public class AnnotationsPropertySource extends EnumerablePropertySource<Class<?>
|
|||
|
||||
private Map<String, Object> getProperties(Class<?> source) {
|
||||
Map<String, Object> properties = new LinkedHashMap<String, Object>();
|
||||
collectProperties(source, properties);
|
||||
collectProperties(source, source, properties);
|
||||
return Collections.unmodifiableMap(properties);
|
||||
}
|
||||
|
||||
private void collectProperties(Class<?> source, Map<String, Object> properties) {
|
||||
private void collectProperties(Class<?> root, Class<?> source,
|
||||
Map<String, Object> properties) {
|
||||
if (source != null) {
|
||||
for (Annotation annotation : AnnotationUtils.getAnnotations(source)) {
|
||||
for (Annotation annotation : getMergedAnnotations(root, source)) {
|
||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation)) {
|
||||
annotation.annotationType().getAnnotation(PropertyMapping.class);
|
||||
PropertyMapping typeMapping = annotation.annotationType()
|
||||
.getAnnotation(PropertyMapping.class);
|
||||
for (Method attribute : annotation.annotationType()
|
||||
.getDeclaredMethods()) {
|
||||
collectProperties(annotation, attribute, typeMapping, properties);
|
||||
}
|
||||
collectProperties(annotation.annotationType(), properties);
|
||||
collectProperties(root, annotation.annotationType(), properties);
|
||||
}
|
||||
}
|
||||
collectProperties(source.getSuperclass(), properties);
|
||||
collectProperties(root, source.getSuperclass(), properties);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Annotation> getMergedAnnotations(Class<?> root, Class<?> source) {
|
||||
List<Annotation> mergedAnnotations = new ArrayList<Annotation>();
|
||||
for (Annotation annotation : AnnotationUtils.getAnnotations(source)) {
|
||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation)) {
|
||||
mergedAnnotations.add(AnnotatedElementUtils.getMergedAnnotation(root,
|
||||
annotation.annotationType()));
|
||||
}
|
||||
}
|
||||
return mergedAnnotations;
|
||||
}
|
||||
|
||||
private void collectProperties(Annotation annotation, Method attribute,
|
||||
PropertyMapping typeMapping, Map<String, Object> properties) {
|
||||
PropertyMapping attributeMapping = AnnotationUtils.getAnnotation(attribute,
|
||||
|
|
|
@ -23,6 +23,8 @@ import org.junit.Rule;
|
|||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
|
@ -154,6 +156,14 @@ public class AnnotationsPropertySourceTests {
|
|||
assertThat(source.getProperty("test.example")).isEqualTo("charlie");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertyMappedAttributesCanBeAliased() {
|
||||
AnnotationsPropertySource source = new AnnotationsPropertySource(
|
||||
PropertyMappedAttributeWithAnAlias.class);
|
||||
assertThat(source.getPropertyNames()).containsExactly("aliasing.value");
|
||||
assertThat(source.getProperty("aliasing.value")).isEqualTo("baz");
|
||||
}
|
||||
|
||||
static class NoAnnotation {
|
||||
|
||||
}
|
||||
|
@ -307,4 +317,28 @@ public class AnnotationsPropertySourceTests {
|
|||
|
||||
}
|
||||
|
||||
@AttributeWithAliasAnnotation("baz")
|
||||
static class PropertyMappedAttributeWithAnAlias {
|
||||
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@AliasedAttributeAnnotation
|
||||
static @interface AttributeWithAliasAnnotation {
|
||||
|
||||
@AliasFor(annotation = AliasedAttributeAnnotation.class, attribute = "value")
|
||||
String value() default "foo";
|
||||
|
||||
String someOtherAttribute() default "shouldNotBeMapped";
|
||||
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@PropertyMapping("aliasing")
|
||||
static @interface AliasedAttributeAnnotation {
|
||||
|
||||
String value() default "bar";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue