Skip to content

Commit a305e2d

Browse files
BenchmarkingBuffalowilkinsona
authored andcommitted
Support @Name with JavaBean-based configuration properties
See gh-39452
1 parent c790deb commit a305e2d

File tree

4 files changed

+60
-4
lines changed

4 files changed

+60
-4
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/JavaBeanBinder.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
*
4747
* @author Phillip Webb
4848
* @author Madhura Bhave
49+
* @author Lasse Wulff
4950
*/
5051
class JavaBeanBinder implements DataObjectBinder {
5152

@@ -92,7 +93,7 @@ private <T> boolean bind(DataObjectPropertyBinder propertyBinder, Bean<T> bean,
9293

9394
private <T> boolean bind(BeanSupplier<T> beanSupplier, DataObjectPropertyBinder propertyBinder,
9495
BeanProperty property) {
95-
String propertyName = property.getName();
96+
String propertyName = determinePropertyName(property);
9697
ResolvableType type = property.getType();
9798
Supplier<Object> value = property.getValue(beanSupplier);
9899
Annotation[] annotations = property.getAnnotations();
@@ -110,6 +111,15 @@ else if (value == null || !bound.equals(value.get())) {
110111
return true;
111112
}
112113

114+
private String determinePropertyName(BeanProperty property) {
115+
return Arrays.stream((property.getAnnotations() != null) ? property.getAnnotations() : new Annotation[0])
116+
.filter((annotation) -> annotation.annotationType() == Name.class)
117+
.findFirst()
118+
.map(Name.class::cast)
119+
.map(Name::value)
120+
.orElse(property.getName());
121+
}
122+
113123
/**
114124
* The properties of a bean that may be bound.
115125
*/

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/Name.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,16 @@
2323
import java.lang.annotation.Target;
2424

2525
/**
26-
* Annotation that can be used to specify the name when binding to an immutable property.
27-
* This annotation may be required when binding to names that clash with reserved language
26+
* Annotation that can be used to specify the name when binding to a property. This
27+
* annotation may be required when binding to names that clash with reserved language
2828
* keywords.
2929
*
3030
* @author Phillip Webb
31+
* @author Lasse Wulff
3132
* @since 2.4.0
3233
*/
3334
@Retention(RetentionPolicy.RUNTIME)
34-
@Target(ElementType.PARAMETER)
35+
@Target({ ElementType.FIELD, ElementType.PARAMETER })
3536
@Documented
3637
public @interface Name {
3738

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/JavaBeanBinderTests.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
* @author Phillip Webb
5353
* @author Madhura Bhave
5454
* @author Andy Wilkinson
55+
* @author Lasse Wulff
5556
*/
5657
class JavaBeanBinderTests {
5758

@@ -74,6 +75,16 @@ void bindToClassShouldCreateBoundBean() {
7475
assertThat(bean.getEnumValue()).isEqualTo(ExampleEnum.FOO_BAR);
7576
}
7677

78+
@Test
79+
void bindRenamedPropertyToClassBean() {
80+
MockConfigurationPropertySource source = new MockConfigurationPropertySource();
81+
source.put("renamed.public", "alpha");
82+
this.sources.add(source);
83+
ExampleRenamedPropertyBean bean = this.binder.bind("renamed", Bindable.of(ExampleRenamedPropertyBean.class))
84+
.get();
85+
assertThat(bean.getExampleProperty()).isEqualTo("alpha");
86+
}
87+
7788
@Test
7889
void bindToClassWhenHasNoPrefixShouldCreateBoundBean() {
7990
MockConfigurationPropertySource source = new MockConfigurationPropertySource();
@@ -648,6 +659,21 @@ void setEnumValue(ExampleEnum enumValue) {
648659

649660
}
650661

662+
static class ExampleRenamedPropertyBean {
663+
664+
@Name("public")
665+
private String exampleProperty;
666+
667+
String getExampleProperty() {
668+
return this.exampleProperty;
669+
}
670+
671+
void setExampleProperty(String exampleProperty) {
672+
this.exampleProperty = exampleProperty;
673+
}
674+
675+
}
676+
651677
static class ExampleDefaultsBean {
652678

653679
private int foo = 123;

spring-boot-project/spring-boot/src/test/kotlin/org/springframework/boot/context/properties/KotlinConfigurationPropertiesTests.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,13 @@ import org.springframework.context.annotation.Import
2626
import org.springframework.test.context.support.TestPropertySourceUtils
2727

2828
import org.assertj.core.api.Assertions.assertThat
29+
import org.springframework.boot.context.properties.bind.Name
2930

3031
/**
3132
* Tests for {@link ConfigurationProperties @ConfigurationProperties}-annotated beans.
3233
*
3334
* @author Madhura Bhave
35+
* @author Lasse Wulff
3436
*/
3537
class KotlinConfigurationPropertiesTests {
3638

@@ -59,6 +61,14 @@ class KotlinConfigurationPropertiesTests {
5961
assertThat(this.context.getBean(LateInitProperties::class.java).inner.value).isEqualTo("alpha")
6062
}
6163

64+
@Test
65+
fun `renamed property can be bound to late init attribute`() {
66+
this.context.register(EnableRenamedLateInitProperties::class.java)
67+
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(this.context, "renamed.var=beta")
68+
this.context.refresh()
69+
assertThat(this.context.getBean(RenamedLateInitProperties::class.java).bar).isEqualTo("beta")
70+
}
71+
6272
@Test
6373
fun `type with constructor bound lateinit property with default can be bound`() {
6474
this.context.register(EnableLateInitPropertiesWithDefault::class.java)
@@ -80,6 +90,15 @@ class KotlinConfigurationPropertiesTests {
8090
@ConfigurationProperties(prefix = "foo")
8191
class BingProperties(@Suppress("UNUSED_PARAMETER") bar: String)
8292

93+
@ConfigurationProperties(prefix = "renamed")
94+
class RenamedLateInitProperties{
95+
@Name("var")
96+
lateinit var bar: String
97+
}
98+
99+
@EnableConfigurationProperties(RenamedLateInitProperties::class)
100+
class EnableRenamedLateInitProperties
101+
83102
@EnableConfigurationProperties
84103
class EnableConfigProperties
85104

0 commit comments

Comments
 (0)