AbstractApplicationContext registers default embedded value resolver

Issue: SPR-14140
This commit is contained in:
Juergen Hoeller
2016-04-09 20:49:22 +02:00
parent 572e535fba
commit cb9549655c
4 changed files with 51 additions and 7 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2016 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.
@@ -209,6 +209,13 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
*/
void addEmbeddedValueResolver(StringValueResolver valueResolver);
/**
* Determine whether an embedded value resolver has been registered with this
* bean factory, to be applied through {@link #resolveEmbeddedValue(String)}.
* @since 4.3
*/
boolean hasEmbeddedValueResolver();
/**
* Resolve the given embedded value, e.g. an annotation attribute.
* @param value the value to resolve

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 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.
@@ -798,6 +798,11 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
this.embeddedValueResolvers.add(valueResolver);
}
@Override
public boolean hasEmbeddedValueResolver() {
return !this.embeddedValueResolvers.isEmpty();
}
@Override
public String resolveEmbeddedValue(String value) {
String result = value;

View File

@@ -78,6 +78,7 @@ import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringValueResolver;
/**
* Abstract implementation of the {@link org.springframework.context.ApplicationContext}
@@ -825,6 +826,18 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return getEnvironment().resolvePlaceholders(strVal);
}
});
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {

View File

@@ -51,7 +51,8 @@ public class RequestHeaderMethodArgumentResolverTests {
private MethodParameter paramNamedValueStringArray;
private MethodParameter paramSystemProperty;
private MethodParameter paramContextPath;
private MethodParameter paramResolvedName;
private MethodParameter paramResolvedNameWithExpression;
private MethodParameter paramResolvedNameWithPlaceholder;
private MethodParameter paramNamedValueMap;
private MockHttpServletRequest servletRequest;
@@ -71,8 +72,9 @@ public class RequestHeaderMethodArgumentResolverTests {
paramNamedValueStringArray = new SynthesizingMethodParameter(method, 1);
paramSystemProperty = new SynthesizingMethodParameter(method, 2);
paramContextPath = new SynthesizingMethodParameter(method, 3);
paramResolvedName = new SynthesizingMethodParameter(method, 4);
paramNamedValueMap = new SynthesizingMethodParameter(method, 5);
paramResolvedNameWithExpression = new SynthesizingMethodParameter(method, 4);
paramResolvedNameWithPlaceholder = new SynthesizingMethodParameter(method, 5);
paramNamedValueMap = new SynthesizingMethodParameter(method, 6);
servletRequest = new MockHttpServletRequest();
webRequest = new ServletWebRequest(servletRequest, new MockHttpServletResponse());
@@ -135,13 +137,29 @@ public class RequestHeaderMethodArgumentResolverTests {
}
@Test
public void resolveNameFromSystemProperty() throws Exception {
public void resolveNameFromSystemPropertyThroughExpression() throws Exception {
String expected = "foo";
servletRequest.addHeader("bar", expected);
System.setProperty("systemProperty", "bar");
try {
Object result = resolver.resolveArgument(paramResolvedName, null, webRequest, null);
Object result = resolver.resolveArgument(paramResolvedNameWithExpression, null, webRequest, null);
assertTrue(result instanceof String);
assertEquals("Invalid result", expected, result);
}
finally {
System.clearProperty("systemProperty");
}
}
@Test
public void resolveNameFromSystemPropertyThroughPlaceholder() throws Exception {
String expected = "foo";
servletRequest.addHeader("bar", expected);
System.setProperty("systemProperty", "bar");
try {
Object result = resolver.resolveArgument(paramResolvedNameWithPlaceholder, null, webRequest, null);
assertTrue(result instanceof String);
assertEquals("Invalid result", expected, result);
}
@@ -171,6 +189,7 @@ public class RequestHeaderMethodArgumentResolverTests {
@RequestHeader(name = "name", defaultValue="#{systemProperties.systemProperty}") String param3,
@RequestHeader(name = "name", defaultValue="#{request.contextPath}") String param4,
@RequestHeader("#{systemProperties.systemProperty}") String param5,
@RequestHeader("${systemProperty}") String param6,
@RequestHeader("name") Map<?, ?> unsupported) {
}