Ensure unresolvable placeholders can be ignored with @Value
Prior to this commit, if a PropertySourcesPlaceholderConfigurer bean
was configured with its ignoreUnresolvablePlaceholders flag set to
true, unresolvable placeholders in an @Value annotation were not
ignored, resulting in a BeanCreationException for the bean using @Value.
For example, given a property declared as `my.app.var = ${var}` without
a corresponding `var` property declared, an attempt to resolve
`@Value("${my.app.var}")` resulted in the following exception.
java.lang.IllegalArgumentException: Could not resolve placeholder 'var' in value "${var}"
This commit fixes this by modifying
PropertySourcesPlaceholderConfigurer's postProcessBeanFactory(...)
method so that a local PropertyResolver is created if the
ignoreUnresolvablePlaceholders flag is set to true. The local
PropertyResolver then enforces that flag, since the Environment in the
ApplicationContext is most likely not configured with
ignoreUnresolvablePlaceholders set to true.
Closes gh-27947
This commit is contained in:
@@ -21,9 +21,14 @@ import java.util.Properties;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.testfixture.beans.TestBean;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
@@ -40,8 +45,11 @@ import static org.springframework.beans.factory.support.BeanDefinitionBuilder.ge
|
||||
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition;
|
||||
|
||||
/**
|
||||
* Tests for {@link PropertySourcesPlaceholderConfigurer}.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @since 3.1
|
||||
*/
|
||||
public class PropertySourcesPlaceholderConfigurerTests {
|
||||
@@ -159,8 +167,11 @@ public class PropertySourcesPlaceholderConfigurerTests {
|
||||
|
||||
PropertySourcesPlaceholderConfigurer ppc = new PropertySourcesPlaceholderConfigurer();
|
||||
//pc.setIgnoreUnresolvablePlaceholders(false); // the default
|
||||
assertThatExceptionOfType(BeanDefinitionStoreException.class).isThrownBy(() ->
|
||||
ppc.postProcessBeanFactory(bf));
|
||||
assertThatExceptionOfType(BeanDefinitionStoreException.class)
|
||||
.isThrownBy(() -> ppc.postProcessBeanFactory(bf))
|
||||
.havingCause()
|
||||
.isExactlyInstanceOf(IllegalArgumentException.class)
|
||||
.withMessage("Could not resolve placeholder 'my.name' in value \"${my.name}\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -177,6 +188,38 @@ public class PropertySourcesPlaceholderConfigurerTests {
|
||||
assertThat(bf.getBean(TestBean.class).getName()).isEqualTo("${my.name}");
|
||||
}
|
||||
|
||||
@Test
|
||||
// https://github.com/spring-projects/spring-framework/issues/27947
|
||||
public void ignoreUnresolvablePlaceholdersInAtValueAnnotation__falseIsDefault() {
|
||||
MockPropertySource mockPropertySource = new MockPropertySource("test");
|
||||
mockPropertySource.setProperty("my.key", "${enigma}");
|
||||
@SuppressWarnings("resource")
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
context.getEnvironment().getPropertySources().addLast(mockPropertySource);
|
||||
context.register(IgnoreUnresolvablePlaceholdersFalseConfig.class);
|
||||
|
||||
assertThatExceptionOfType(BeanCreationException.class)
|
||||
.isThrownBy(context::refresh)
|
||||
.havingCause()
|
||||
.isExactlyInstanceOf(IllegalArgumentException.class)
|
||||
.withMessage("Could not resolve placeholder 'enigma' in value \"${enigma}\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
// https://github.com/spring-projects/spring-framework/issues/27947
|
||||
public void ignoreUnresolvablePlaceholdersInAtValueAnnotation_true() {
|
||||
MockPropertySource mockPropertySource = new MockPropertySource("test");
|
||||
mockPropertySource.setProperty("my.key", "${enigma}");
|
||||
@SuppressWarnings("resource")
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
context.getEnvironment().getPropertySources().addLast(mockPropertySource);
|
||||
context.register(IgnoreUnresolvablePlaceholdersTrueConfig.class);
|
||||
context.refresh();
|
||||
|
||||
IgnoreUnresolvablePlaceholdersTrueConfig config = context.getBean(IgnoreUnresolvablePlaceholdersTrueConfig.class);
|
||||
assertThat(config.value).isEqualTo("${enigma}");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("serial")
|
||||
public void nestedUnresolvablePlaceholder() {
|
||||
@@ -402,4 +445,30 @@ public class PropertySourcesPlaceholderConfigurerTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class IgnoreUnresolvablePlaceholdersFalseConfig {
|
||||
|
||||
@Value("${my.key}")
|
||||
String value;
|
||||
|
||||
@Bean
|
||||
static PropertySourcesPlaceholderConfigurer pspc() {
|
||||
return new PropertySourcesPlaceholderConfigurer();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class IgnoreUnresolvablePlaceholdersTrueConfig {
|
||||
|
||||
@Value("${my.key}")
|
||||
String value;
|
||||
|
||||
@Bean
|
||||
static PropertySourcesPlaceholderConfigurer pspc() {
|
||||
PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
|
||||
pspc.setIgnoreUnresolvablePlaceholders(true);
|
||||
return pspc;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user