From ba70b7965123634114ccde3e2404ee89c3eb1c04 Mon Sep 17 00:00:00 2001 From: Vlad Kisel Date: Sun, 7 Jun 2020 19:19:12 +0200 Subject: [PATCH 1/2] Allow data unit to be specified on the constructor parameter See gh-21746 --- .../boot/convert/DataSizeUnit.java | 5 +- .../boot/convert/DurationUnit.java | 5 +- .../boot/convert/PeriodUnit.java | 3 +- .../ConfigurationPropertiesTests.java | 77 +++++++++++++++++++ 4 files changed, 85 insertions(+), 5 deletions(-) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/DataSizeUnit.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/DataSizeUnit.java index 658868e6459..7e9bc45d81e 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/DataSizeUnit.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/DataSizeUnit.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,9 +30,10 @@ import org.springframework.util.unit.DataUnit; * {@link DataSize}. * * @author Stephane Nicoll + * @author Vladislav Kisel * @since 2.1.0 */ -@Target(ElementType.FIELD) +@Target({ ElementType.FIELD, ElementType.PARAMETER }) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface DataSizeUnit { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/DurationUnit.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/DurationUnit.java index c8b60c9b538..b21057f601e 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/DurationUnit.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/DurationUnit.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,9 +29,10 @@ import java.time.temporal.ChronoUnit; * {@link Duration}. * * @author Phillip Webb + * @author Vladislav Kisel * @since 2.0.0 */ -@Target(ElementType.FIELD) +@Target({ ElementType.FIELD, ElementType.PARAMETER }) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface DurationUnit { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/PeriodUnit.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/PeriodUnit.java index e34c43948af..ea337e38d6a 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/PeriodUnit.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/PeriodUnit.java @@ -30,9 +30,10 @@ import java.time.temporal.ChronoUnit; * * @author Eddú Meléndez * @author Edson Chávez + * @author Vladislav Kisel * @since 2.3.0 */ -@Target(ElementType.FIELD) +@Target({ ElementType.FIELD, ElementType.PARAMETER }) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface PeriodUnit { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/ConfigurationPropertiesTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/ConfigurationPropertiesTests.java index 3ebdac21185..e5fc2e16c5d 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/ConfigurationPropertiesTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/ConfigurationPropertiesTests.java @@ -19,6 +19,8 @@ package org.springframework.boot.context.properties; import java.beans.PropertyEditorSupport; import java.io.File; import java.time.Duration; +import java.time.Period; +import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -54,6 +56,8 @@ import org.springframework.boot.context.properties.bind.DefaultValue; import org.springframework.boot.context.properties.bind.validation.BindValidationException; import org.springframework.boot.context.properties.source.ConfigurationPropertyName; import org.springframework.boot.convert.DataSizeUnit; +import org.springframework.boot.convert.DurationUnit; +import org.springframework.boot.convert.PeriodUnit; import org.springframework.boot.testsupport.system.CapturedOutput; import org.springframework.boot.testsupport.system.OutputCaptureExtension; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -107,6 +111,7 @@ import static org.mockito.Mockito.verify; * @author Phillip Webb * @author Stephane Nicoll * @author Madhura Bhave + * @author Vladislav Kisel */ @ExtendWith(OutputCaptureExtension.class) class ConfigurationPropertiesTests { @@ -129,6 +134,14 @@ class ConfigurationPropertiesTests { assertThat(this.context.getBean(BasicProperties.class).name).isEqualTo("foo"); } + @Test + void testConverting() { + load(BasicConfiguration.class, "name=foo"); + assertThat(this.context.getBeanNamesForType(BasicProperties.class)).hasSize(1); + assertThat(this.context.containsBean(BasicProperties.class.getName())).isTrue(); + assertThat(this.context.getBean(BasicProperties.class).name).isEqualTo("foo"); + } + @Test void loadShouldBindNested() { load(NestedConfiguration.class, "name=foo", "nested.name=bar"); @@ -762,6 +775,22 @@ class ConfigurationPropertiesTests { assertThat(bean.getBar()).isEqualTo(5); } + @Test + void loadWhenBindingToConstructorParametersWithConversionShouldBind() { + MutablePropertySources sources = this.context.getEnvironment().getPropertySources(); + Map source = new HashMap<>(); + source.put("test.size", "2"); + source.put("test.duration", "5"); + source.put("test.period", "6"); + sources.addLast(new MapPropertySource("test", source)); + load(ConstructorParameterWithConversionConfiguration.class); + ConstructorParameterWithConversionProperties bean = this.context + .getBean(ConstructorParameterWithConversionProperties.class); + assertThat(bean.getSize()).isEqualTo(DataSize.ofMegabytes(2)); + assertThat(bean.getDuration()).isEqualTo(Duration.ofDays(5)); + assertThat(bean.getPeriod()).isEqualTo(Period.ofYears(6)); + } + @Test // gh-17831 void loadWhenBindingConstructorParametersViaImportShouldThrowException() { assertThatExceptionOfType(BeanCreationException.class) @@ -777,6 +806,16 @@ class ConfigurationPropertiesTests { assertThat(bean.getBar()).isEqualTo(0); } + @Test + void loadWhenBindingToConstructorParametersWithConversionAndDefaultValuesShouldBind() { + load(ConstructorParameterWithConversionConfiguration.class); + ConstructorParameterWithConversionProperties bean = this.context + .getBean(ConstructorParameterWithConversionProperties.class); + assertThat(bean.getPeriod()).isEqualTo(Period.ofYears(4)); + assertThat(bean.getSize()).isEqualTo(DataSize.ofMegabytes(3)); + assertThat(bean.getDuration()).isEqualTo(Duration.ofDays(2)); + } + @Test void loadWhenBindingToConstructorParametersShouldValidate() { assertThatExceptionOfType(Exception.class) @@ -1933,6 +1972,39 @@ class ConfigurationPropertiesTests { } + @ConstructorBinding + @ConfigurationProperties(prefix = "test") + @Validated + static class ConstructorParameterWithConversionProperties { + + private final DataSize size; + + private final Duration duration; + + private final Period period; + + ConstructorParameterWithConversionProperties(@DefaultValue("4") @PeriodUnit(ChronoUnit.YEARS) Period period, + @DefaultValue("3") @DataSizeUnit(DataUnit.MEGABYTES) DataSize size, + @DefaultValue("2") @DurationUnit(ChronoUnit.DAYS) Duration duration) { + this.size = size; + this.duration = duration; + this.period = period; + } + + Period getPeriod() { + return this.period; + } + + DataSize getSize() { + return this.size; + } + + Duration getDuration() { + return this.duration; + } + + } + @Configuration(proxyBeanMethods = false) @EnableConfigurationProperties @Import(ConstructorParameterProperties.class) @@ -1963,6 +2035,11 @@ class ConfigurationPropertiesTests { } + @EnableConfigurationProperties(ConstructorParameterWithConversionProperties.class) + static class ConstructorParameterWithConversionConfiguration { + + } + @EnableConfigurationProperties(ConstructorParameterValidatedProperties.class) static class ConstructorParameterValidationConfiguration { From 429a504bbe37176c93c76c0b715aa938102f4479 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 7 Jul 2020 13:56:49 +0200 Subject: [PATCH 2/2] Polish "Allow data unit to be specified on the constructor parameter" See gh-21746 --- .../docs/asciidoc/spring-boot-features.adoc | 19 ++++- .../bind/constructor/AppIoProperties.java | 56 +++++++++++++ .../bind/constructor/AppSystemProperties.java | 57 +++++++++++++ .../bind/{ => javabean}/AppIoProperties.java | 4 +- .../{ => javabean}/AppSystemProperties.java | 4 +- .../constructor/AppSystemPropertiesTests.java | 81 +++++++++++++++++++ .../AppSystemPropertiesTests.java | 2 +- .../boot/convert/DataSizeUnit.java | 1 - .../boot/convert/DurationUnit.java | 1 - .../boot/convert/PeriodUnit.java | 1 - .../ConfigurationPropertiesTests.java | 63 +++++++-------- 11 files changed, 243 insertions(+), 46 deletions(-) create mode 100644 spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/context/properties/bind/constructor/AppIoProperties.java create mode 100644 spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/context/properties/bind/constructor/AppSystemProperties.java rename spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/context/properties/bind/{ => javabean}/AppIoProperties.java (92%) rename spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/context/properties/bind/{ => javabean}/AppSystemProperties.java (92%) create mode 100644 spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/context/properties/bind/constructor/AppSystemPropertiesTests.java rename spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/context/properties/bind/{ => javabean}/AppSystemPropertiesTests.java (97%) diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/spring-boot-features.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/spring-boot-features.adoc index 0d331ef0063..2d34c20703f 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/spring-boot-features.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/spring-boot-features.adoc @@ -1426,7 +1426,7 @@ Consider the following example: [source,java,indent=0] ---- -include::{code-examples}/context/properties/bind/AppSystemProperties.java[tag=example] +include::{code-examples}/context/properties/bind/javabean/AppSystemProperties.java[tag=example] ---- To specify a session timeout of 30 seconds, `30`, `PT30S` and `30s` are all equivalent. @@ -1445,6 +1445,14 @@ These are: The default unit is milliseconds and can be overridden using `@DurationUnit` as illustrated in the sample above. +If you prefer to use constructor binding, the same properties can be exposed, as shown in the following example: + +[source,java,indent=0] +---- +include::{code-examples}/context/properties/bind/constructor/AppSystemProperties.java[tag=example] +---- + + TIP: If you are upgrading a `Long` property, make sure to define the unit (using `@DurationUnit`) if it isn't milliseconds. Doing so gives a transparent upgrade path while supporting a much richer format. @@ -1482,7 +1490,7 @@ Consider the following example: [source,java,indent=0] ---- -include::{code-examples}/context/properties/bind/AppIoProperties.java[tag=example] +include::{code-examples}/context/properties/bind/javabean/AppIoProperties.java[tag=example] ---- To specify a buffer size of 10 megabytes, `10` and `10MB` are equivalent. @@ -1499,6 +1507,13 @@ These are: The default unit is bytes and can be overridden using `@DataSizeUnit` as illustrated in the sample above. +If you prefer to use constructor binding, the same properties can be exposed, as shown in the following example: + +[source,java,indent=0] +---- +include::{code-examples}/context/properties/bind/constructor/AppIoProperties.java[tag=example] +---- + TIP: If you are upgrading a `Long` property, make sure to define the unit (using `@DataSizeUnit`) if it isn't bytes. Doing so gives a transparent upgrade path while supporting a much richer format. diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/context/properties/bind/constructor/AppIoProperties.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/context/properties/bind/constructor/AppIoProperties.java new file mode 100644 index 00000000000..86bcb9e76a5 --- /dev/null +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/context/properties/bind/constructor/AppIoProperties.java @@ -0,0 +1,56 @@ +/* + * Copyright 2012-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.docs.context.properties.bind.constructor; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.ConstructorBinding; +import org.springframework.boot.context.properties.bind.DefaultValue; +import org.springframework.boot.convert.DataSizeUnit; +import org.springframework.util.unit.DataSize; +import org.springframework.util.unit.DataUnit; + +/** + * A {@link ConfigurationProperties @ConfigurationProperties} example that uses + * {@link DataSize}. + * + * @author Stephane Nicoll + */ +// tag::example[] +@ConfigurationProperties("app.io") +@ConstructorBinding +public class AppIoProperties { + + private final DataSize bufferSize; + + private final DataSize sizeThreshold; + + public AppIoProperties(@DataSizeUnit(DataUnit.MEGABYTES) @DefaultValue("2MB") DataSize bufferSize, + @DefaultValue("512B") DataSize sizeThreshold) { + this.bufferSize = bufferSize; + this.sizeThreshold = sizeThreshold; + } + + public DataSize getBufferSize() { + return this.bufferSize; + } + + public DataSize getSizeThreshold() { + return this.sizeThreshold; + } + +} +// end::example[] diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/context/properties/bind/constructor/AppSystemProperties.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/context/properties/bind/constructor/AppSystemProperties.java new file mode 100644 index 00000000000..d30b635c839 --- /dev/null +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/context/properties/bind/constructor/AppSystemProperties.java @@ -0,0 +1,57 @@ +/* + * Copyright 2012-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.docs.context.properties.bind.constructor; + +import java.time.Duration; +import java.time.temporal.ChronoUnit; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.ConstructorBinding; +import org.springframework.boot.context.properties.bind.DefaultValue; +import org.springframework.boot.convert.DurationUnit; + +/** + * A {@link ConfigurationProperties @ConfigurationProperties} example that uses + * {@link Duration}. + * + * @author Stephane Nicoll + */ +// tag::example[] +@ConfigurationProperties("app.system") +@ConstructorBinding +public class AppSystemProperties { + + private final Duration sessionTimeout; + + private final Duration readTimeout; + + public AppSystemProperties(@DurationUnit(ChronoUnit.SECONDS) @DefaultValue("30s") Duration sessionTimeout, + @DefaultValue("1000ms") Duration readTimeout) { + this.sessionTimeout = sessionTimeout; + this.readTimeout = readTimeout; + } + + public Duration getSessionTimeout() { + return this.sessionTimeout; + } + + public Duration getReadTimeout() { + return this.readTimeout; + } + +} +// end::example[] diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/context/properties/bind/AppIoProperties.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/context/properties/bind/javabean/AppIoProperties.java similarity index 92% rename from spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/context/properties/bind/AppIoProperties.java rename to spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/context/properties/bind/javabean/AppIoProperties.java index 4a89b76034e..15862ff55f4 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/context/properties/bind/AppIoProperties.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/context/properties/bind/javabean/AppIoProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docs.context.properties.bind; +package org.springframework.boot.docs.context.properties.bind.javabean; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.convert.DataSizeUnit; diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/context/properties/bind/AppSystemProperties.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/context/properties/bind/javabean/AppSystemProperties.java similarity index 92% rename from spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/context/properties/bind/AppSystemProperties.java rename to spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/context/properties/bind/javabean/AppSystemProperties.java index 230d267033a..eca2bb44071 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/context/properties/bind/AppSystemProperties.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/context/properties/bind/javabean/AppSystemProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docs.context.properties.bind; +package org.springframework.boot.docs.context.properties.bind.javabean; import java.time.Duration; import java.time.temporal.ChronoUnit; diff --git a/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/context/properties/bind/constructor/AppSystemPropertiesTests.java b/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/context/properties/bind/constructor/AppSystemPropertiesTests.java new file mode 100644 index 00000000000..f64e4958968 --- /dev/null +++ b/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/context/properties/bind/constructor/AppSystemPropertiesTests.java @@ -0,0 +1,81 @@ +/* + * Copyright 2012-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.docs.context.properties.bind.constructor; + +import java.util.function.Consumer; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.assertj.AssertableApplicationContext; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.test.context.runner.ContextConsumer; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link AppSystemProperties}. + * + * @author Stephane Nicoll + */ +class AppSystemPropertiesTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withUserConfiguration(Config.class); + + @Test + void bindWithDefaultUnit() { + this.contextRunner.withPropertyValues("app.system.session-timeout=40", "app.system.read-timeout=5000") + .run(assertBinding((properties) -> { + assertThat(properties.getSessionTimeout()).hasSeconds(40); + assertThat(properties.getReadTimeout()).hasMillis(5000); + })); + } + + @Test + void bindWithExplicitUnit() { + this.contextRunner.withPropertyValues("app.system.session-timeout=1h", "app.system.read-timeout=5s") + .run(assertBinding((properties) -> { + assertThat(properties.getSessionTimeout()).hasMinutes(60); + assertThat(properties.getReadTimeout()).hasMillis(5000); + })); + } + + @Test + void bindWithIso8601Format() { + this.contextRunner.withPropertyValues("app.system.session-timeout=PT15S", "app.system.read-timeout=PT0.5S") + .run(assertBinding((properties) -> { + assertThat(properties.getSessionTimeout()).hasSeconds(15); + assertThat(properties.getReadTimeout()).hasMillis(500); + })); + } + + private ContextConsumer assertBinding(Consumer properties) { + return (context) -> { + assertThat(context).hasSingleBean(AppSystemProperties.class); + properties.accept(context.getBean(AppSystemProperties.class)); + }; + } + + @Configuration(proxyBeanMethods = false) + @EnableConfigurationProperties(AppSystemProperties.class) + static class Config { + + } + +} diff --git a/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/context/properties/bind/AppSystemPropertiesTests.java b/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/context/properties/bind/javabean/AppSystemPropertiesTests.java similarity index 97% rename from spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/context/properties/bind/AppSystemPropertiesTests.java rename to spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/context/properties/bind/javabean/AppSystemPropertiesTests.java index f6fd2d21f43..f9155f5a0cc 100644 --- a/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/context/properties/bind/AppSystemPropertiesTests.java +++ b/spring-boot-project/spring-boot-docs/src/test/java/org/springframework/boot/docs/context/properties/bind/javabean/AppSystemPropertiesTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.docs.context.properties.bind; +package org.springframework.boot.docs.context.properties.bind.javabean; import java.util.function.Consumer; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/DataSizeUnit.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/DataSizeUnit.java index 7e9bc45d81e..c68ac8dbe3b 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/DataSizeUnit.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/DataSizeUnit.java @@ -30,7 +30,6 @@ import org.springframework.util.unit.DataUnit; * {@link DataSize}. * * @author Stephane Nicoll - * @author Vladislav Kisel * @since 2.1.0 */ @Target({ ElementType.FIELD, ElementType.PARAMETER }) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/DurationUnit.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/DurationUnit.java index b21057f601e..ab70d284df7 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/DurationUnit.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/DurationUnit.java @@ -29,7 +29,6 @@ import java.time.temporal.ChronoUnit; * {@link Duration}. * * @author Phillip Webb - * @author Vladislav Kisel * @since 2.0.0 */ @Target({ ElementType.FIELD, ElementType.PARAMETER }) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/PeriodUnit.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/PeriodUnit.java index ea337e38d6a..c2f3d1ba6b9 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/PeriodUnit.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/PeriodUnit.java @@ -30,7 +30,6 @@ import java.time.temporal.ChronoUnit; * * @author Eddú Meléndez * @author Edson Chávez - * @author Vladislav Kisel * @since 2.3.0 */ @Target({ ElementType.FIELD, ElementType.PARAMETER }) diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/ConfigurationPropertiesTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/ConfigurationPropertiesTests.java index e5fc2e16c5d..e26fd815af0 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/ConfigurationPropertiesTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/ConfigurationPropertiesTests.java @@ -134,14 +134,6 @@ class ConfigurationPropertiesTests { assertThat(this.context.getBean(BasicProperties.class).name).isEqualTo("foo"); } - @Test - void testConverting() { - load(BasicConfiguration.class, "name=foo"); - assertThat(this.context.getBeanNamesForType(BasicProperties.class)).hasSize(1); - assertThat(this.context.containsBean(BasicProperties.class.getName())).isTrue(); - assertThat(this.context.getBean(BasicProperties.class).name).isEqualTo("foo"); - } - @Test void loadShouldBindNested() { load(NestedConfiguration.class, "name=foo", "nested.name=bar"); @@ -776,19 +768,19 @@ class ConfigurationPropertiesTests { } @Test - void loadWhenBindingToConstructorParametersWithConversionShouldBind() { + void loadWhenBindingToConstructorParametersWithCustomDataUnitShouldBind() { MutablePropertySources sources = this.context.getEnvironment().getPropertySources(); Map source = new HashMap<>(); - source.put("test.size", "2"); - source.put("test.duration", "5"); - source.put("test.period", "6"); + source.put("test.duration", "12"); + source.put("test.size", "13"); + source.put("test.period", "14"); sources.addLast(new MapPropertySource("test", source)); - load(ConstructorParameterWithConversionConfiguration.class); - ConstructorParameterWithConversionProperties bean = this.context - .getBean(ConstructorParameterWithConversionProperties.class); - assertThat(bean.getSize()).isEqualTo(DataSize.ofMegabytes(2)); - assertThat(bean.getDuration()).isEqualTo(Duration.ofDays(5)); - assertThat(bean.getPeriod()).isEqualTo(Period.ofYears(6)); + load(ConstructorParameterWithUnitConfiguration.class); + ConstructorParameterWithUnitProperties bean = this.context + .getBean(ConstructorParameterWithUnitProperties.class); + assertThat(bean.getDuration()).isEqualTo(Duration.ofDays(12)); + assertThat(bean.getSize()).isEqualTo(DataSize.ofMegabytes(13)); + assertThat(bean.getPeriod()).isEqualTo(Period.ofYears(14)); } @Test // gh-17831 @@ -807,13 +799,13 @@ class ConfigurationPropertiesTests { } @Test - void loadWhenBindingToConstructorParametersWithConversionAndDefaultValuesShouldBind() { - load(ConstructorParameterWithConversionConfiguration.class); - ConstructorParameterWithConversionProperties bean = this.context - .getBean(ConstructorParameterWithConversionProperties.class); - assertThat(bean.getPeriod()).isEqualTo(Period.ofYears(4)); - assertThat(bean.getSize()).isEqualTo(DataSize.ofMegabytes(3)); + void loadWhenBindingToConstructorParametersWithDefaultDataUnitShouldBind() { + load(ConstructorParameterWithUnitConfiguration.class); + ConstructorParameterWithUnitProperties bean = this.context + .getBean(ConstructorParameterWithUnitProperties.class); assertThat(bean.getDuration()).isEqualTo(Duration.ofDays(2)); + assertThat(bean.getSize()).isEqualTo(DataSize.ofMegabytes(3)); + assertThat(bean.getPeriod()).isEqualTo(Period.ofYears(4)); } @Test @@ -1974,33 +1966,32 @@ class ConfigurationPropertiesTests { @ConstructorBinding @ConfigurationProperties(prefix = "test") - @Validated - static class ConstructorParameterWithConversionProperties { - - private final DataSize size; + static class ConstructorParameterWithUnitProperties { private final Duration duration; + private final DataSize size; + private final Period period; - ConstructorParameterWithConversionProperties(@DefaultValue("4") @PeriodUnit(ChronoUnit.YEARS) Period period, + ConstructorParameterWithUnitProperties(@DefaultValue("2") @DurationUnit(ChronoUnit.DAYS) Duration duration, @DefaultValue("3") @DataSizeUnit(DataUnit.MEGABYTES) DataSize size, - @DefaultValue("2") @DurationUnit(ChronoUnit.DAYS) Duration duration) { + @DefaultValue("4") @PeriodUnit(ChronoUnit.YEARS) Period period) { this.size = size; this.duration = duration; this.period = period; } - Period getPeriod() { - return this.period; + Duration getDuration() { + return this.duration; } DataSize getSize() { return this.size; } - Duration getDuration() { - return this.duration; + Period getPeriod() { + return this.period; } } @@ -2035,8 +2026,8 @@ class ConfigurationPropertiesTests { } - @EnableConfigurationProperties(ConstructorParameterWithConversionProperties.class) - static class ConstructorParameterWithConversionConfiguration { + @EnableConfigurationProperties(ConstructorParameterWithUnitProperties.class) + static class ConstructorParameterWithUnitConfiguration { }