Skip to content

Commit 914452b

Browse files
dreis2211wilkinsona
authored andcommitted
Allow DurationFormat and PeriodFormat to be used on parameters
See gh-22646
1 parent c7bfc01 commit 914452b

File tree

3 files changed

+84
-3
lines changed

3 files changed

+84
-3
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/DurationFormat.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -30,7 +30,7 @@
3030
* @author Phillip Webb
3131
* @since 2.0.0
3232
*/
33-
@Target(ElementType.FIELD)
33+
@Target({ ElementType.FIELD, ElementType.PARAMETER })
3434
@Retention(RetentionPolicy.RUNTIME)
3535
@Documented
3636
public @interface DurationFormat {

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/PeriodFormat.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
* @author Edson Chávez
3232
* @since 2.3.0
3333
*/
34-
@Target(ElementType.FIELD)
34+
@Target({ ElementType.FIELD, ElementType.PARAMETER })
3535
@Retention(RetentionPolicy.RUNTIME)
3636
@Documented
3737
public @interface PeriodFormat {

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

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,11 @@
5656
import org.springframework.boot.context.properties.bind.validation.BindValidationException;
5757
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
5858
import org.springframework.boot.convert.DataSizeUnit;
59+
import org.springframework.boot.convert.DurationFormat;
60+
import org.springframework.boot.convert.DurationStyle;
5961
import org.springframework.boot.convert.DurationUnit;
62+
import org.springframework.boot.convert.PeriodFormat;
63+
import org.springframework.boot.convert.PeriodStyle;
6064
import org.springframework.boot.convert.PeriodUnit;
6165
import org.springframework.boot.testsupport.system.CapturedOutput;
6266
import org.springframework.boot.testsupport.system.OutputCaptureExtension;
@@ -808,6 +812,53 @@ void loadWhenBindingToConstructorParametersWithDefaultDataUnitShouldBind() {
808812
assertThat(bean.getPeriod()).isEqualTo(Period.ofYears(4));
809813
}
810814

815+
@Test
816+
void loadWhenBindingToConstructorParametersWithCustomDataFormatShouldBind() {
817+
MutablePropertySources sources = this.context.getEnvironment().getPropertySources();
818+
Map<String, Object> source = new HashMap<>();
819+
source.put("test.duration", "12d");
820+
source.put("test.period", "13y");
821+
sources.addLast(new MapPropertySource("test", source));
822+
load(ConstructorParameterWithFormatConfiguration.class);
823+
ConstructorParameterWithFormatProperties bean = this.context
824+
.getBean(ConstructorParameterWithFormatProperties.class);
825+
assertThat(bean.getDuration()).isEqualTo(Duration.ofDays(12));
826+
assertThat(bean.getPeriod()).isEqualTo(Period.ofYears(13));
827+
}
828+
829+
@Test
830+
void loadWhenBindingToConstructorParametersWithNotMatchingCustomDurationFormatShouldFail() {
831+
MutablePropertySources sources = this.context.getEnvironment().getPropertySources();
832+
Map<String, Object> source = new HashMap<>();
833+
source.put("test.duration", "P12D");
834+
sources.addLast(new MapPropertySource("test", source));
835+
assertThatExceptionOfType(Exception.class)
836+
.isThrownBy(() -> load(ConstructorParameterWithFormatConfiguration.class)).satisfies((ex) -> {
837+
assertThat(ex).hasCauseInstanceOf(BindException.class);
838+
});
839+
}
840+
841+
@Test
842+
void loadWhenBindingToConstructorParametersWithNotMatchingCustomPeriodFormatShouldFail() {
843+
MutablePropertySources sources = this.context.getEnvironment().getPropertySources();
844+
Map<String, Object> source = new HashMap<>();
845+
source.put("test.period", "P12D");
846+
sources.addLast(new MapPropertySource("test", source));
847+
assertThatExceptionOfType(Exception.class)
848+
.isThrownBy(() -> load(ConstructorParameterWithFormatConfiguration.class)).satisfies((ex) -> {
849+
assertThat(ex).hasCauseInstanceOf(BindException.class);
850+
});
851+
}
852+
853+
@Test
854+
void loadWhenBindingToConstructorParametersWithDefaultDataFormatShouldBind() {
855+
load(ConstructorParameterWithFormatConfiguration.class);
856+
ConstructorParameterWithFormatProperties bean = this.context
857+
.getBean(ConstructorParameterWithFormatProperties.class);
858+
assertThat(bean.getDuration()).isEqualTo(Duration.ofDays(2));
859+
assertThat(bean.getPeriod()).isEqualTo(Period.ofYears(3));
860+
}
861+
811862
@Test
812863
void loadWhenBindingToConstructorParametersShouldValidate() {
813864
assertThatExceptionOfType(Exception.class)
@@ -2007,6 +2058,31 @@ Period getPeriod() {
20072058

20082059
}
20092060

2061+
@ConstructorBinding
2062+
@ConfigurationProperties(prefix = "test")
2063+
static class ConstructorParameterWithFormatProperties {
2064+
2065+
private final Duration duration;
2066+
2067+
private final Period period;
2068+
2069+
ConstructorParameterWithFormatProperties(
2070+
@DefaultValue("2d") @DurationFormat(DurationStyle.SIMPLE) Duration duration,
2071+
@DefaultValue("3y") @PeriodFormat(PeriodStyle.SIMPLE) Period period) {
2072+
this.duration = duration;
2073+
this.period = period;
2074+
}
2075+
2076+
Duration getDuration() {
2077+
return this.duration;
2078+
}
2079+
2080+
Period getPeriod() {
2081+
return this.period;
2082+
}
2083+
2084+
}
2085+
20102086
@ConstructorBinding
20112087
@ConfigurationProperties(prefix = "test")
20122088
@Validated
@@ -2035,6 +2111,11 @@ static class ConstructorParameterWithUnitConfiguration {
20352111

20362112
}
20372113

2114+
@EnableConfigurationProperties(ConstructorParameterWithFormatProperties.class)
2115+
static class ConstructorParameterWithFormatConfiguration {
2116+
2117+
}
2118+
20382119
@EnableConfigurationProperties(ConstructorParameterValidatedProperties.class)
20392120
static class ConstructorParameterValidationConfiguration {
20402121

0 commit comments

Comments
 (0)