From 08a0f22a9577bc6c77654f909f926ebeb7455562 Mon Sep 17 00:00:00 2001 From: Dean Wette Date: Thu, 9 Nov 2023 13:26:41 -0600 Subject: [PATCH 1/3] Document it is possible to use Java Records for immutable configuration with @ConfigurationProperties closes #10086 --- .../docs/guide/config/immutableConfig.adoc | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/main/docs/guide/config/immutableConfig.adoc b/src/main/docs/guide/config/immutableConfig.adoc index 5cfdd951702..cb7990699c9 100644 --- a/src/main/docs/guide/config/immutableConfig.adoc +++ b/src/main/docs/guide/config/immutableConfig.adoc @@ -55,6 +55,26 @@ snippet::io.micronaut.docs.config.immutable.VehicleSpec[tags="start",indent=0,ti The above example prints: `"Ford Engine Starting V8 [rodLength=7B.0]"` +==== Using Java Record Classes to define immutable configuration + +For Java language applications, it's also possible to use https://docs.oracle.com/en/java/javase/17/language/records.html[Java Record Classes] for immutable configuration with ann:context.annotation.ConfigurationProperties[]. For example: + +[source, java] +---- +import io.micronaut.context.annotation.ConfigurationProperties; +import io.micronaut.core.annotation.NonNull; +import jakarta.validation.constraints.NotNull; +import java.math.BigDecimal; + +@ConfigurationProperties("vat") +public record ValueAddedTaxConfiguration( + @NonNull @NotNull BigDecimal percentage) { // <1> +} +---- +<1> The `percentage` field defines a configuration property for "vat" + +NOTE: From a performance perspective Java records are better than interfaces; however, they have the disadvantage of not supporting link:{api}/io/micronaut/runtime/context/scope/Refreshable.html[@Refreshable]. Use one of the other mechanisms for immutable configuration if that's a requirement. + == Customizing accessors As already explained in <>, it is also possible to customize the accessors when creating immutable configuration properties: From 13f635b818c80d23f8e3f22c4a703f1e90ad47a4 Mon Sep 17 00:00:00 2001 From: Dean Wette Date: Fri, 10 Nov 2023 11:04:56 -0600 Subject: [PATCH 2/3] Change Java record example to snippet, with test. --- .../docs/guide/config/immutableConfig.adoc | 12 +-------- .../immutable/ValueAddedTaxConfiguration.java | 17 +++++++++++++ .../ValueAddedTaxConfigurationTest.java | 25 +++++++++++++++++++ 3 files changed, 43 insertions(+), 11 deletions(-) create mode 100644 test-suite/src/test/java/io/micronaut/docs/config/immutable/ValueAddedTaxConfiguration.java create mode 100644 test-suite/src/test/java/io/micronaut/docs/config/immutable/ValueAddedTaxConfigurationTest.java diff --git a/src/main/docs/guide/config/immutableConfig.adoc b/src/main/docs/guide/config/immutableConfig.adoc index cb7990699c9..5aefd4c5cf3 100644 --- a/src/main/docs/guide/config/immutableConfig.adoc +++ b/src/main/docs/guide/config/immutableConfig.adoc @@ -59,18 +59,8 @@ The above example prints: `"Ford Engine Starting V8 [rodLength=7B.0]"` For Java language applications, it's also possible to use https://docs.oracle.com/en/java/javase/17/language/records.html[Java Record Classes] for immutable configuration with ann:context.annotation.ConfigurationProperties[]. For example: -[source, java] ----- -import io.micronaut.context.annotation.ConfigurationProperties; -import io.micronaut.core.annotation.NonNull; -import jakarta.validation.constraints.NotNull; -import java.math.BigDecimal; +snippet::io.micronaut.docs.config.immutable.ValueAddedTaxConfiguration[tags="imports,class",title="Java Record Example"] -@ConfigurationProperties("vat") -public record ValueAddedTaxConfiguration( - @NonNull @NotNull BigDecimal percentage) { // <1> -} ----- <1> The `percentage` field defines a configuration property for "vat" NOTE: From a performance perspective Java records are better than interfaces; however, they have the disadvantage of not supporting link:{api}/io/micronaut/runtime/context/scope/Refreshable.html[@Refreshable]. Use one of the other mechanisms for immutable configuration if that's a requirement. diff --git a/test-suite/src/test/java/io/micronaut/docs/config/immutable/ValueAddedTaxConfiguration.java b/test-suite/src/test/java/io/micronaut/docs/config/immutable/ValueAddedTaxConfiguration.java new file mode 100644 index 00000000000..a096bf8c65b --- /dev/null +++ b/test-suite/src/test/java/io/micronaut/docs/config/immutable/ValueAddedTaxConfiguration.java @@ -0,0 +1,17 @@ +package io.micronaut.docs.config.immutable; + +// tag::imports[] +import io.micronaut.context.annotation.ConfigurationProperties; +import io.micronaut.context.annotation.Requires; +import io.micronaut.core.annotation.NonNull; +import jakarta.validation.constraints.NotNull; +import java.math.BigDecimal; +// end::imports[] + +@Requires(property="spec.name", value="ValueAddedTaxConfigurationTest") +// tag::class[] +@ConfigurationProperties("vat") +public record ValueAddedTaxConfiguration( + @NonNull @NotNull BigDecimal percentage) { // <1> +} +// end::class[] diff --git a/test-suite/src/test/java/io/micronaut/docs/config/immutable/ValueAddedTaxConfigurationTest.java b/test-suite/src/test/java/io/micronaut/docs/config/immutable/ValueAddedTaxConfigurationTest.java new file mode 100644 index 00000000000..2ebd1d5b0b1 --- /dev/null +++ b/test-suite/src/test/java/io/micronaut/docs/config/immutable/ValueAddedTaxConfigurationTest.java @@ -0,0 +1,25 @@ +package io.micronaut.docs.config.immutable; + +import io.micronaut.context.BeanContext; +import io.micronaut.context.annotation.Property; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; +import java.math.BigDecimal; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@Property(name = "spec.name", value="ValueAddedTaxConfigurationTest") +@Property(name = "vat.percentage", value = "21.0") +@MicronautTest(startApplication = false) +class ValueAddedTaxConfigurationTest { + + @Inject + BeanContext beanContext; + + @Test + void immutableConfigurationViaJavaRecords() { + assertTrue(beanContext.containsBean(ValueAddedTaxConfiguration.class)); + assertEquals(new BigDecimal("21.0"), beanContext.getBean(ValueAddedTaxConfiguration.class).percentage()); + } +} From b131e40ceb9dcc75ab623667c9d28127c316478c Mon Sep 17 00:00:00 2001 From: Dean Wette Date: Fri, 10 Nov 2023 13:49:44 -0600 Subject: [PATCH 3/3] Remove statement about @Refreshable, pending clarity (and a test). --- src/main/docs/guide/config/immutableConfig.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/docs/guide/config/immutableConfig.adoc b/src/main/docs/guide/config/immutableConfig.adoc index 5aefd4c5cf3..480aec8e99e 100644 --- a/src/main/docs/guide/config/immutableConfig.adoc +++ b/src/main/docs/guide/config/immutableConfig.adoc @@ -63,7 +63,7 @@ snippet::io.micronaut.docs.config.immutable.ValueAddedTaxConfiguration[tags="imp <1> The `percentage` field defines a configuration property for "vat" -NOTE: From a performance perspective Java records are better than interfaces; however, they have the disadvantage of not supporting link:{api}/io/micronaut/runtime/context/scope/Refreshable.html[@Refreshable]. Use one of the other mechanisms for immutable configuration if that's a requirement. +NOTE: From a performance perspective Java records are better than interfaces. == Customizing accessors