From 90be94a4a548b11dc12be38f1d15f867ad90c611 Mon Sep 17 00:00:00 2001 From: Sam Brannen <104798+sbrannen@users.noreply.github.com> Date: Mon, 26 May 2025 18:28:47 +0200 Subject: [PATCH] Use ConversionService from Environment in PropertySourcesPlaceholderConfigurer This commit fixes a regression in PropertySourcesPlaceholderConfigurer that was introduced in Spring Framework 6.2.7. Specifically, this commit reinstates automatic String-conversion of values from PropertySources in the Environment using the ConversionService configured in the Environment. See gh-34861 Closes gh-34936 --- .../PropertySourcesPlaceholderConfigurer.java | 31 +++++++++++++++++-- ...ertySourcesPlaceholderConfigurerTests.java | 2 -- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurer.java b/spring-context/src/main/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurer.java index 7df8bf086ae..97bbfc32bad 100644 --- a/spring-context/src/main/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurer.java +++ b/spring-context/src/main/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurer.java @@ -24,6 +24,8 @@ import org.springframework.beans.factory.BeanInitializationException; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.PlaceholderConfigurerSupport; import org.springframework.context.EnvironmentAware; +import org.springframework.core.convert.ConversionService; +import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.ConfigurablePropertyResolver; import org.springframework.core.env.Environment; @@ -243,16 +245,38 @@ public class PropertySourcesPlaceholderConfigurer extends PlaceholderConfigurerS @Override @Nullable - public Object getProperty(String name) { + // Declare String as covariant return type, since a String is actually required. + public String getProperty(String name) { for (PropertySource propertySource : super.source.getPropertySources()) { Object candidate = propertySource.getProperty(name); if (candidate != null) { - return candidate; + return convertToString(candidate); } } return null; } + /** + * Convert the supplied value to a {@link String} using the {@link ConversionService} + * from the {@link Environment}. + *

This is a modified version of + * {@link org.springframework.core.env.AbstractPropertyResolver#convertValueIfNecessary(Object, Class)}. + * @param value the value to convert + * @return the converted value, or the original value if no conversion is necessary + * @since 6.2.8 + */ + @Nullable + private String convertToString(Object value) { + if (value instanceof String string) { + return string; + } + ConversionService conversionService = super.source.getConversionService(); + if (conversionService == null) { + conversionService = DefaultConversionService.getSharedInstance(); + } + return conversionService.convert(value, String.class); + } + @Override public String toString() { return "ConfigurableEnvironmentPropertySource {propertySources=" + super.source.getPropertySources() + "}"; @@ -279,7 +303,8 @@ public class PropertySourcesPlaceholderConfigurer extends PlaceholderConfigurerS @Override @Nullable - public Object getProperty(String name) { + // Declare String as covariant return type, since a String is actually required. + public String getProperty(String name) { return super.source.getProperty(name); } diff --git a/spring-context/src/test/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurerTests.java b/spring-context/src/test/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurerTests.java index 8e8cdef9455..71c9eeea73b 100644 --- a/spring-context/src/test/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurerTests.java +++ b/spring-context/src/test/java/org/springframework/context/support/PropertySourcesPlaceholderConfigurerTests.java @@ -25,7 +25,6 @@ import java.util.Properties; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -98,7 +97,6 @@ class PropertySourcesPlaceholderConfigurerTests { * used by the {@code Environment} is applied during placeholder resolution * against a {@link PropertySource} registered in the {@code Environment}. */ - @Disabled("Disabled until gh-34936 is resolved") @Test // gh-34936 void replacementFromEnvironmentPropertiesWithConversion() { DefaultListableBeanFactory bf = new DefaultListableBeanFactory();