4

I'm trying to figure out how to get the values of a properties file into my Spring Environment properties.

The pre Spring 3.1 way of doing this would be something like:

 <context:property-placeholder location="classpath:my.properties" /> <bean id="myBean" class="com.whatever.MyBean"> <property name="someValue" value="${myProps.value}" /> <!-- etc --> </bean> 

I could have also done this:

public class MyBean { @Value(value = "#{myProps.value}") private String someValue; } 

Now that I can ostensibly pull properties from the Environment class, this seems like a much cleaner way of getting properties than using the clunky #{myProps.value} syntax in either my xml or my bean itself.

I tried this in my XML:

<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"> <property name="location"> <value>classpath:my.properties</value> </property> </bean> 

But the properties are not added to Environment.

I understand that I can use the PropertySource attribute, but I'm not doing my configuration with annotations.

So how can I set up my bean / xml so that variables setup in my props are available in Environment? Moreover, how can I inject those values into my bean without having to explicitly say "environmentInstance.getProperty("myProps.value")?

2
  • 1
    Perhaps I'm misunderstanding what Environment buys me? Commented Jan 8, 2013 at 20:57
  • I have edited the answer - environment has wider applicability because it works not only for the bean definitions but for other things like <import/> statement etc. Commented Jan 9, 2013 at 0:37

2 Answers 2

1

For the web applications

If you want to have Environment populated before the XML bean definitions are processed, you should implement a ApplicationContextInitializer(), as described in the Spring Source blog

<context-param> <param-name>contextInitializerClasses</param-name> <param-value>com.bank.MyInitializer</param-value> </context-param> 

Here is a slightly modified version of the example from the blog

public class MyInitializer implements ApplicationContextInitializer<ConfigurableWebApplicationContext> { public void initialize(ConfigurableWebApplicationContext ctx) { ResourcePropertySource ps; try { ps = new ResourcePropertySource(new ClassPathResource( "my.properties")); } catch (IOException e) { throw new AssertionError("Resources for my.properties not found."); } ctx.getEnvironment().getPropertySources().addFirst(ps); } } 

For the standalone applications

Basically the same thing, you can modify the environment of the AbstractApplicationContext directly

 ResourcePropertySource ps; try { ps = new ResourcePropertySource(new ClassPathResource( "my.properties")); }catch (IOException e) { throw new AssertionError("Resources for my.properties not found."); } //assuming that ctx is an AbstractApplicationContext ctx.getEnvironment().getPropertySources().addFirst(ps); 

P.S. the earlier version of this answer showed an attempt to modify the Environment from the bean but it seems to be an antipattern spreading on SO, because for sure you would like to have Environment property sources list populated even before the XmlBeanDefinitionReader starts to process XML to make placeholders work inside the <import/> statement.

Sign up to request clarification or add additional context in comments.

Comments

0

My understanding is also a little addled but this is what I could make out:

  1. Environment is a way to indicate the currently active profiles (and profiles are a way to selectively create beans)
  2. PropertySources can be associated to an environment and the way to do that is using @PropertySource annotation, there does not seem to be an xml equivalent to do this.
  3. Your understanding actually should be the other way round, AFAIK: when you declare <context:property-placeholder the placeholder will resolve properties against the locally declared properties and can fallback on the property sources declared in the environment, environment itself does not get modified with the new properties. Again,the only way to add properties to the environment itself seems to be through the @PropertySource annotation

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.