Skip to content

Commit 8ae78b6

Browse files
committed
Add tests to ensure @Autowired or private constructor is not used for value object binding
Sometimes we want to duplicate `@ConfigurationProperties` bean with different prefix, we should use the primary configuration properties as default of additional configuration properties instead of re-configuring them all, then we could inject that primary bean and copy its values as default via constructor, there are two ways to force constructor used for injection instead of binding, annotating it with `@Autowired` or marking it as `private`.
1 parent 8628f73 commit 8ae78b6

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

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

Lines changed: 77 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 autowiredConstructorShouldInjectBeanInsteadOfBindProperties() {
1276+
load(ServicePropertiesConfiguration.class, "primary.service.port=1234", "foo.service.host=127.0.0.1");
1277+
PrimaryServiceProperties primaryServiceProperties = this.context.getBean(PrimaryServiceProperties.class);
1278+
assertThat(primaryServiceProperties.getHost()).isEqualTo("localhost");
1279+
assertThat(primaryServiceProperties.getPort()).isEqualTo(1234);
1280+
FooServiceProperties fooServiceProperties = this.context.getBean(FooServiceProperties.class);
1281+
assertThat(fooServiceProperties.getHost()).isEqualTo("127.0.0.1");
1282+
assertThat(fooServiceProperties.getPort()).isEqualTo(1234);
1283+
}
1284+
1285+
@Test
1286+
void privateConstructorShouldInjectBeanInsteadOfBindProperties() {
1287+
load(ServicePropertiesConfiguration.class, "primary.service.port=1234", "bar.service.host=127.0.0.1");
1288+
BarServiceProperties barServiceProperties = this.context.getBean(BarServiceProperties.class);
1289+
assertThat(barServiceProperties.getHost()).isEqualTo("127.0.0.1");
1290+
assertThat(barServiceProperties.getPort()).isEqualTo(1234);
1291+
}
1292+
12731293
private AnnotationConfigApplicationContext load(Class<?> configuration, String... inlinedProperties) {
12741294
return load(new Class<?>[] { configuration }, inlinedProperties);
12751295
}
@@ -3310,4 +3330,61 @@ static final class CustomList<E> extends ArrayList<E> {
33103330

33113331
}
33123332

3333+
static abstract class ServiceProperties {
3334+
3335+
private String host = "localhost";
3336+
3337+
private int port = 1000;
3338+
3339+
public String getHost() {
3340+
return this.host;
3341+
}
3342+
3343+
public void setHost(String host) {
3344+
this.host = host;
3345+
}
3346+
3347+
public int getPort() {
3348+
return this.port;
3349+
}
3350+
3351+
public void setPort(int port) {
3352+
this.port = port;
3353+
}
3354+
3355+
}
3356+
3357+
@ConfigurationProperties("primary.service")
3358+
static class PrimaryServiceProperties extends ServiceProperties {
3359+
3360+
}
3361+
3362+
@ConfigurationProperties("foo.service")
3363+
static class FooServiceProperties extends ServiceProperties {
3364+
3365+
@Autowired
3366+
public FooServiceProperties(PrimaryServiceProperties serviceProperties) {
3367+
// should use BeanUtils.copyProperties(serviceProperties, this) in practice
3368+
setHost(serviceProperties.getHost());
3369+
setPort(serviceProperties.getPort());
3370+
}
3371+
3372+
}
3373+
3374+
@ConfigurationProperties("bar.service")
3375+
static class BarServiceProperties extends ServiceProperties {
3376+
3377+
private BarServiceProperties(PrimaryServiceProperties serviceProperties) {
3378+
setHost(serviceProperties.getHost());
3379+
setPort(serviceProperties.getPort());
3380+
}
3381+
3382+
}
3383+
3384+
@EnableConfigurationProperties({ PrimaryServiceProperties.class, FooServiceProperties.class,
3385+
BarServiceProperties.class })
3386+
static class ServicePropertiesConfiguration {
3387+
3388+
}
3389+
33133390
}

0 commit comments

Comments
 (0)