Skip to content

Commit

Permalink
Support to inherit common properties for configuring multiple beans
Browse files Browse the repository at this point in the history
It's used for configuring multiple beans (spring-projects#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();
	}
```
  • Loading branch information
quaff committed Oct 12, 2024
1 parent 35361d1 commit 0487c58
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
* values are externalized.
*
* @author Dave Syer
* @author Yanming Zhou
* @since 1.0.0
* @see ConfigurationPropertiesScan
* @see ConstructorBinding
Expand Down Expand Up @@ -69,6 +70,14 @@
@AliasFor("value")
String prefix() default "";

/**
* The prefix of the properties that {@link #prefix()} will inherit, It's used for
* configuring multiple beans which share common properties.
* @return the prefix of the properties to inherit
* @see #prefix()
*/
String inheritedPrefix() default "";

/**
* Flag to indicate that when binding to this object invalid fields should be ignored.
* Invalid means invalid according to the binder that is used, and usually this means
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@
* @author Stephane Nicoll
* @author Madhura Bhave
* @author Vladislav Kisel
* @author Yanming Zhou
*/
@ExtendWith(OutputCaptureExtension.class)
class ConfigurationPropertiesTests {
Expand Down Expand Up @@ -1270,6 +1271,25 @@ void loadWhenBindingToJavaBeanWithConversionToCustomListImplementation() {
assertThat(this.context.getBean(SetterBoundCustomListProperties.class).getValues()).containsExactly("a", "b");
}

@Test
void loadWhenUsingInheritedPrefixForJavaBeanBinder() {
load(SetterBoundInheritedPrefixConfiguration.class, "spring.service.host=127.0.0.1", "spring.service.port=6379",
"additional.service.port=6380");
SetterBoundServiceProperties properties = this.context.getBean("additionalServiceProperties",
SetterBoundServiceProperties.class);
assertThat(properties.getPort()).isEqualTo(6380);
assertThat(properties.getHost()).isEqualTo("127.0.0.1");
}

@Test
void loadWhenUsingInheritedPrefixForValueObjectBinder() {
load(ConstructorBoundInheritedPrefixConfiguration.class, "spring.service.host=127.0.0.1",
"spring.service.port=6379", "additional.service.port=6380");
ConstructorBoundServiceProperties properties = this.context.getBean(ConstructorBoundServiceProperties.class);
assertThat(properties.getPort()).isEqualTo(6380);
assertThat(properties.getHost()).isEqualTo("127.0.0.1");
}

private AnnotationConfigApplicationContext load(Class<?> configuration, String... inlinedProperties) {
return load(new Class<?>[] { configuration }, inlinedProperties);
}
Expand Down Expand Up @@ -3310,4 +3330,68 @@ static final class CustomList<E> extends ArrayList<E> {

}

@ConfigurationProperties(prefix = "spring.service")
static class SetterBoundServiceProperties {

private String host = "localhost";

private int port = 6379;

String getHost() {
return this.host;
}

void setHost(String host) {
this.host = host;
}

int getPort() {
return this.port;
}

void setPort(int port) {
this.port = port;
}

}

@EnableConfigurationProperties(SetterBoundServiceProperties.class)
static class SetterBoundInheritedPrefixConfiguration {

@Bean(autowireCandidate = false) // do not back off auto-configured one
@ConfigurationProperties(prefix = "additional.service", inheritedPrefix = "spring.service")
SetterBoundServiceProperties additionalServiceProperties() {
return new SetterBoundServiceProperties();
}

}

@ConfigurationProperties(prefix = "additional.service", inheritedPrefix = "spring.service")
static class ConstructorBoundServiceProperties {

private final String host;

private final int port;

public ConstructorBoundServiceProperties(@DefaultValue("localhost") String host,
@DefaultValue("6379") int port) {
this.host = host;
this.port = port;
}

String getHost() {
return this.host;
}

int getPort() {
return this.port;
}

}

@EnableConfigurationProperties(ConstructorBoundServiceProperties.class)
static class ConstructorBoundInheritedPrefixConfiguration {

}

}

0 comments on commit 0487c58

Please sign in to comment.