Skip to content

Commit 0487c58

Browse files
committed
Support to inherit common properties for configuring multiple beans
It's used for configuring multiple beans (#15732), we could extract common or use primary properties as parent now. Take `org.springframework.boot.autoconfigure.data.redis.RedisProperties` for example, given: ``` # primary spring.data.redis: host: 127.0.0.1 port: 6379 # additional additional.data.redis: port: 6380 ``` Then effective properties: ``` additional.data.redis: host: 127.0.0.1 port: 6380 ``` should be bound to `additionalRedisProperties`: ```java @bean(autowireCandidate = false) // do not back off autoconfigured one @ConfigurationProperties(prefix = "additional.data.redis", inheritedPrefix = "spring.data.redis") RedisProperties additionalRedisProperties() { return new RedisProperties(); } ```
1 parent 35361d1 commit 0487c58

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
* values are externalized.
4040
*
4141
* @author Dave Syer
42+
* @author Yanming Zhou
4243
* @since 1.0.0
4344
* @see ConfigurationPropertiesScan
4445
* @see ConstructorBinding
@@ -69,6 +70,14 @@
6970
@AliasFor("value")
7071
String prefix() default "";
7172

73+
/**
74+
* The prefix of the properties that {@link #prefix()} will inherit, It's used for
75+
* configuring multiple beans which share common properties.
76+
* @return the prefix of the properties to inherit
77+
* @see #prefix()
78+
*/
79+
String inheritedPrefix() default "";
80+
7281
/**
7382
* Flag to indicate that when binding to this object invalid fields should be ignored.
7483
* Invalid means invalid according to the binder that is used, and usually this means

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

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
* @author Stephane Nicoll
129129
* @author Madhura Bhave
130130
* @author Vladislav Kisel
131+
* @author Yanming Zhou
131132
*/
132133
@ExtendWith(OutputCaptureExtension.class)
133134
class ConfigurationPropertiesTests {
@@ -1270,6 +1271,25 @@ void loadWhenBindingToJavaBeanWithConversionToCustomListImplementation() {
12701271
assertThat(this.context.getBean(SetterBoundCustomListProperties.class).getValues()).containsExactly("a", "b");
12711272
}
12721273

1274+
@Test
1275+
void loadWhenUsingInheritedPrefixForJavaBeanBinder() {
1276+
load(SetterBoundInheritedPrefixConfiguration.class, "spring.service.host=127.0.0.1", "spring.service.port=6379",
1277+
"additional.service.port=6380");
1278+
SetterBoundServiceProperties properties = this.context.getBean("additionalServiceProperties",
1279+
SetterBoundServiceProperties.class);
1280+
assertThat(properties.getPort()).isEqualTo(6380);
1281+
assertThat(properties.getHost()).isEqualTo("127.0.0.1");
1282+
}
1283+
1284+
@Test
1285+
void loadWhenUsingInheritedPrefixForValueObjectBinder() {
1286+
load(ConstructorBoundInheritedPrefixConfiguration.class, "spring.service.host=127.0.0.1",
1287+
"spring.service.port=6379", "additional.service.port=6380");
1288+
ConstructorBoundServiceProperties properties = this.context.getBean(ConstructorBoundServiceProperties.class);
1289+
assertThat(properties.getPort()).isEqualTo(6380);
1290+
assertThat(properties.getHost()).isEqualTo("127.0.0.1");
1291+
}
1292+
12731293
private AnnotationConfigApplicationContext load(Class<?> configuration, String... inlinedProperties) {
12741294
return load(new Class<?>[] { configuration }, inlinedProperties);
12751295
}
@@ -3310,4 +3330,68 @@ static final class CustomList<E> extends ArrayList<E> {
33103330

33113331
}
33123332

3333+
@ConfigurationProperties(prefix = "spring.service")
3334+
static class SetterBoundServiceProperties {
3335+
3336+
private String host = "localhost";
3337+
3338+
private int port = 6379;
3339+
3340+
String getHost() {
3341+
return this.host;
3342+
}
3343+
3344+
void setHost(String host) {
3345+
this.host = host;
3346+
}
3347+
3348+
int getPort() {
3349+
return this.port;
3350+
}
3351+
3352+
void setPort(int port) {
3353+
this.port = port;
3354+
}
3355+
3356+
}
3357+
3358+
@EnableConfigurationProperties(SetterBoundServiceProperties.class)
3359+
static class SetterBoundInheritedPrefixConfiguration {
3360+
3361+
@Bean(autowireCandidate = false) // do not back off auto-configured one
3362+
@ConfigurationProperties(prefix = "additional.service", inheritedPrefix = "spring.service")
3363+
SetterBoundServiceProperties additionalServiceProperties() {
3364+
return new SetterBoundServiceProperties();
3365+
}
3366+
3367+
}
3368+
3369+
@ConfigurationProperties(prefix = "additional.service", inheritedPrefix = "spring.service")
3370+
static class ConstructorBoundServiceProperties {
3371+
3372+
private final String host;
3373+
3374+
private final int port;
3375+
3376+
public ConstructorBoundServiceProperties(@DefaultValue("localhost") String host,
3377+
@DefaultValue("6379") int port) {
3378+
this.host = host;
3379+
this.port = port;
3380+
}
3381+
3382+
String getHost() {
3383+
return this.host;
3384+
}
3385+
3386+
int getPort() {
3387+
return this.port;
3388+
}
3389+
3390+
}
3391+
3392+
@EnableConfigurationProperties(ConstructorBoundServiceProperties.class)
3393+
static class ConstructorBoundInheritedPrefixConfiguration {
3394+
3395+
}
3396+
33133397
}

0 commit comments

Comments
 (0)