From 1014fc2106455b99d573299e505d1a97863933ee Mon Sep 17 00:00:00 2001 From: Bohdan Pryshedko Date: Wed, 30 Jul 2025 15:10:17 +0300 Subject: [PATCH 1/2] Stop using custom name for elements resolution Previously, when a property was customized with @Name, getter, setter, field, and record component were looked up using the custom name, rather than the property name. This lead to missing information as the custom name is not meant to match the field name, for instance. This commit keeps the custom name, but uses the property name as for other cases. See gh-46599 Signed-off-by: Bohdan Pryshedko --- .../PropertyDescriptorResolver.java | 9 +++++---- ...nfigurationMetadataAnnotationProcessorTests.java | 5 +++++ .../configurationsample/record/ExampleRecord.java | 13 ++++++++++++- .../simple/DeprecatedRecord.java | 9 ++++++++- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/PropertyDescriptorResolver.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/PropertyDescriptorResolver.java index b9c8a5e3820..bd7bca0751f 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/PropertyDescriptorResolver.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/PropertyDescriptorResolver.java @@ -86,11 +86,12 @@ class PropertyDescriptorResolver { private PropertyDescriptor extracted(TypeElement declaringElement, TypeElementMembers members, VariableElement parameter) { String name = getPropertyName(parameter); + String parameterName = parameter.getSimpleName().toString(); TypeMirror type = parameter.asType(); - ExecutableElement getter = members.getPublicGetter(name, type); - ExecutableElement setter = members.getPublicSetter(name, type); - VariableElement field = members.getFields().get(name); - RecordComponentElement recordComponent = members.getRecordComponents().get(name); + ExecutableElement getter = members.getPublicGetter(parameterName, type); + ExecutableElement setter = members.getPublicSetter(parameterName, type); + VariableElement field = members.getFields().get(parameterName); + RecordComponentElement recordComponent = members.getRecordComponents().get(parameterName); return (recordComponent != null) ? new RecordParameterPropertyDescriptor(name, type, parameter, declaringElement, getter, recordComponent) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessorTests.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessorTests.java index 2e482fe2ccd..a51aae7c769 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessorTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationprocessor/ConfigurationMetadataAnnotationProcessorTests.java @@ -264,6 +264,9 @@ class ConfigurationMetadataAnnotationProcessorTests extends AbstractMetadataGene .fromSource(type) .withDeprecation("some-reason", null, null)); assertThat(metadata).has(Metadata.withProperty("deprecated-record.bravo", String.class).fromSource(type)); + assertThat(metadata).has(Metadata.withProperty("deprecated-record.named.charlie", String.class) + .fromSource(type) + .withDeprecation("another-reason", null, null)); } @Test @@ -568,6 +571,8 @@ class ConfigurationMetadataAnnotationProcessorTests extends AbstractMetadataGene .withDescription("description without space after asterisk")); assertThat(metadata).has(Metadata.withProperty("record.descriptions.some-byte", Byte.class) .withDescription("last description in Javadoc")); + assertThat(metadata).has(Metadata.withProperty("record.descriptions.named.record.component", String.class) + .withDescription("description of a named component")); } } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/record/ExampleRecord.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/record/ExampleRecord.java index 7d861ed09ac..ce63a3ec796 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/record/ExampleRecord.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/record/ExampleRecord.java @@ -16,6 +16,8 @@ package org.springframework.boot.configurationsample.record; +import org.springframework.boot.configurationsample.Name; + // @formatter:off /** @@ -26,12 +28,21 @@ package org.springframework.boot.configurationsample.record; * @param someInteger description with @param and @ pitfalls * @param someBoolean description with extra spaces * @param someLong description without space after asterisk + * @param namedComponent description of a named component * @param someByte last description in Javadoc * @since 1.0.0 * @author Pavel Anisimov */ @org.springframework.boot.configurationsample.ConfigurationProperties("record.descriptions") -public record ExampleRecord(String someString, Integer someInteger, Boolean someBoolean, Long someLong, Byte someByte) { +public record ExampleRecord( + String someString, + Integer someInteger, + Boolean someBoolean, + Long someLong, + @Name("named.record.component") + String namedComponent, + Byte someByte + ) { } //@formatter:on diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/simple/DeprecatedRecord.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/simple/DeprecatedRecord.java index 517cab7d6ba..45405feb9c6 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/simple/DeprecatedRecord.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/simple/DeprecatedRecord.java @@ -18,16 +18,18 @@ package org.springframework.boot.configurationsample.simple; import org.springframework.boot.configurationsample.ConfigurationProperties; import org.springframework.boot.configurationsample.DeprecatedConfigurationProperty; +import org.springframework.boot.configurationsample.Name; /** * Configuration properties as record with deprecated property. * * @param alpha alpha property, deprecated * @param bravo bravo property + * @param charlie charlie property, named, deprecated * @author Moritz Halbritter */ @ConfigurationProperties("deprecated-record") -public record DeprecatedRecord(String alpha, String bravo) { +public record DeprecatedRecord(String alpha, String bravo, @Name("named.charlie") String charlie) { @Deprecated @DeprecatedConfigurationProperty(reason = "some-reason") @@ -35,4 +37,9 @@ public record DeprecatedRecord(String alpha, String bravo) { return this.alpha; } + @Deprecated + @DeprecatedConfigurationProperty(reason = "another-reason") + public String charlie() { + return this.charlie; + } } From 27d7c5992beaf947cae97b8bf042475010b8401f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Mon, 4 Aug 2025 15:00:08 +0200 Subject: [PATCH 2/2] Polish "Stop using custom name for elements resolution" See gh-46599 --- .../PropertyDescriptorResolver.java | 6 +----- .../record/ExampleRecord.java | 18 +++--------------- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/PropertyDescriptorResolver.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/PropertyDescriptorResolver.java index bd7bca0751f..9bd5fb82c32 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/PropertyDescriptorResolver.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/main/java/org/springframework/boot/configurationprocessor/PropertyDescriptorResolver.java @@ -85,8 +85,8 @@ class PropertyDescriptorResolver { private PropertyDescriptor extracted(TypeElement declaringElement, TypeElementMembers members, VariableElement parameter) { - String name = getPropertyName(parameter); String parameterName = parameter.getSimpleName().toString(); + String name = getPropertyName(parameter, parameterName); TypeMirror type = parameter.asType(); ExecutableElement getter = members.getPublicGetter(parameterName, type); ExecutableElement setter = members.getPublicSetter(parameterName, type); @@ -99,10 +99,6 @@ class PropertyDescriptorResolver { field); } - private String getPropertyName(VariableElement parameter) { - return getPropertyName(parameter, parameter.getSimpleName().toString()); - } - private String getPropertyName(VariableElement parameter, String fallback) { AnnotationMirror nameAnnotation = this.environment.getNameAnnotation(parameter); if (nameAnnotation != null) { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/record/ExampleRecord.java b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/record/ExampleRecord.java index ce63a3ec796..c004f431678 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/record/ExampleRecord.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-configuration-processor/src/test/java/org/springframework/boot/configurationsample/record/ExampleRecord.java @@ -18,13 +18,10 @@ package org.springframework.boot.configurationsample.record; import org.springframework.boot.configurationsample.Name; -// @formatter:off - /** * Example Record Javadoc sample * - * @param someString very long description that - * doesn't fit single line and is indented + * @param someString very long description that doesn't fit single line and is indented * @param someInteger description with @param and @ pitfalls * @param someBoolean description with extra spaces * @param someLong description without space after asterisk @@ -34,15 +31,6 @@ import org.springframework.boot.configurationsample.Name; * @author Pavel Anisimov */ @org.springframework.boot.configurationsample.ConfigurationProperties("record.descriptions") -public record ExampleRecord( - String someString, - Integer someInteger, - Boolean someBoolean, - Long someLong, - @Name("named.record.component") - String namedComponent, - Byte someByte - ) { +public record ExampleRecord(String someString, Integer someInteger, Boolean someBoolean, Long someLong, + @Name("named.record.component") String namedComponent, Byte someByte) { } - -//@formatter:on