diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/UtilNamespaceHandler.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/UtilNamespaceHandler.java index c9e7d8b2ea4..ba6b41ac821 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/UtilNamespaceHandler.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/UtilNamespaceHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 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. @@ -200,6 +200,7 @@ public class UtilNamespaceHandler extends NamespaceHandlerSupport { String location = element.getAttribute("location"); if (StringUtils.hasLength(location)) { + location = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(location); String[] locations = StringUtils.commaDelimitedListToStringArray(location); builder.addPropertyValue("locations", locations); } diff --git a/spring-context/src/main/java/org/springframework/context/config/AbstractPropertyLoadingBeanDefinitionParser.java b/spring-context/src/main/java/org/springframework/context/config/AbstractPropertyLoadingBeanDefinitionParser.java index e77ac952b60..289c1c94847 100644 --- a/spring-context/src/main/java/org/springframework/context/config/AbstractPropertyLoadingBeanDefinitionParser.java +++ b/spring-context/src/main/java/org/springframework/context/config/AbstractPropertyLoadingBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 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. @@ -21,6 +21,7 @@ import org.w3c.dom.Element; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; import org.springframework.util.StringUtils; /** @@ -39,9 +40,10 @@ abstract class AbstractPropertyLoadingBeanDefinitionParser extends AbstractSingl } @Override - protected void doParse(Element element, BeanDefinitionBuilder builder) { + protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { String location = element.getAttribute("location"); if (StringUtils.hasLength(location)) { + location = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(location); String[] locations = StringUtils.commaDelimitedListToStringArray(location); builder.addPropertyValue("locations", locations); } diff --git a/spring-context/src/main/java/org/springframework/context/config/PropertyOverrideBeanDefinitionParser.java b/spring-context/src/main/java/org/springframework/context/config/PropertyOverrideBeanDefinitionParser.java index 4f994d4b2bb..4c5647b4e66 100644 --- a/spring-context/src/main/java/org/springframework/context/config/PropertyOverrideBeanDefinitionParser.java +++ b/spring-context/src/main/java/org/springframework/context/config/PropertyOverrideBeanDefinitionParser.java @@ -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. @@ -20,6 +20,7 @@ import org.w3c.dom.Element; import org.springframework.beans.factory.config.PropertyOverrideConfigurer; import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.ParserContext; /** * Parser for the <context:property-override/> element. @@ -36,8 +37,8 @@ class PropertyOverrideBeanDefinitionParser extends AbstractPropertyLoadingBeanDe } @Override - protected void doParse(Element element, BeanDefinitionBuilder builder) { - super.doParse(element, builder); + protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { + super.doParse(element, parserContext, builder); builder.addPropertyValue("ignoreInvalidKeys", Boolean.valueOf(element.getAttribute("ignore-unresolvable"))); diff --git a/spring-context/src/main/java/org/springframework/context/config/PropertyPlaceholderBeanDefinitionParser.java b/spring-context/src/main/java/org/springframework/context/config/PropertyPlaceholderBeanDefinitionParser.java index cb38e6b0256..3fcbc30a409 100644 --- a/spring-context/src/main/java/org/springframework/context/config/PropertyPlaceholderBeanDefinitionParser.java +++ b/spring-context/src/main/java/org/springframework/context/config/PropertyPlaceholderBeanDefinitionParser.java @@ -20,6 +20,7 @@ import org.w3c.dom.Element; import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.ParserContext; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.util.StringUtils; @@ -54,8 +55,8 @@ class PropertyPlaceholderBeanDefinitionParser extends AbstractPropertyLoadingBea } @Override - protected void doParse(Element element, BeanDefinitionBuilder builder) { - super.doParse(element, builder); + protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { + super.doParse(element, parserContext, builder); builder.addPropertyValue("ignoreUnresolvablePlaceholders", Boolean.valueOf(element.getAttribute("ignore-unresolvable"))); diff --git a/spring-context/src/test/java/org/springframework/context/config/ContextNamespaceHandlerTests.java b/spring-context/src/test/java/org/springframework/context/config/ContextNamespaceHandlerTests.java index ba04db4931b..bf106be77fa 100644 --- a/spring-context/src/test/java/org/springframework/context/config/ContextNamespaceHandlerTests.java +++ b/spring-context/src/test/java/org/springframework/context/config/ContextNamespaceHandlerTests.java @@ -16,12 +16,14 @@ package org.springframework.context.config; +import java.io.FileNotFoundException; import java.util.Calendar; import java.util.Date; import org.junit.After; import org.junit.Test; +import org.springframework.beans.FatalBeanException; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.GenericXmlApplicationContext; @@ -89,6 +91,54 @@ public class ContextNamespaceHandlerTests { assertEquals("maps", applicationContext.getBean("spam")); } + @Test + public void propertyPlaceholderLocationWithSystemPropertyForOneLocation() throws Exception { + System.setProperty("properties", + "classpath*:/org/springframework/context/config/test-*.properties"); + try { + ApplicationContext applicationContext = new ClassPathXmlApplicationContext( + "contextNamespaceHandlerTests-location-placeholder.xml", getClass()); + assertEquals("bar", applicationContext.getBean("foo")); + assertEquals("foo", applicationContext.getBean("bar")); + assertEquals("maps", applicationContext.getBean("spam")); + } + finally { + System.clearProperty("properties"); + } + } + + @Test + public void propertyPlaceholderLocationWithSystemPropertyForMultipleLocations() throws Exception { + System.setProperty("properties", + "classpath*:/org/springframework/context/config/test-*.properties," + + "classpath*:/org/springframework/context/config/empty-*.properties," + + "classpath*:/org/springframework/context/config/missing-*.properties"); + try { + ApplicationContext applicationContext = new ClassPathXmlApplicationContext( + "contextNamespaceHandlerTests-location-placeholder.xml", getClass()); + assertEquals("bar", applicationContext.getBean("foo")); + assertEquals("foo", applicationContext.getBean("bar")); + assertEquals("maps", applicationContext.getBean("spam")); + } + finally { + System.clearProperty("properties"); + } + } + + @Test + public void propertyPlaceholderLocationWithSystemPropertyMissing() throws Exception { + try { + ApplicationContext applicationContext = new ClassPathXmlApplicationContext( + "contextNamespaceHandlerTests-location-placeholder.xml", getClass()); + assertEquals("bar", applicationContext.getBean("foo")); + assertEquals("foo", applicationContext.getBean("bar")); + assertEquals("maps", applicationContext.getBean("spam")); + } + catch (FatalBeanException ex) { + assertTrue(ex.getRootCause() instanceof FileNotFoundException); + } + } + @Test public void propertyPlaceholderIgnored() throws Exception { ApplicationContext applicationContext = new ClassPathXmlApplicationContext( diff --git a/spring-context/src/test/resources/org/springframework/context/config/contextNamespaceHandlerTests-location-placeholder.xml b/spring-context/src/test/resources/org/springframework/context/config/contextNamespaceHandlerTests-location-placeholder.xml new file mode 100644 index 00000000000..8a941ea31a6 --- /dev/null +++ b/spring-context/src/test/resources/org/springframework/context/config/contextNamespaceHandlerTests-location-placeholder.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + +