views:

253

answers:

6

How do you configure a Spring bean container (or application context) to load a Java property file?

JavaWorld article Smartly Load Your Properties explains how to load property files from the classpath using one of the following resource processing methods in the standard Java library:

ClassLoader.getResourceAsStream ("some/pkg/resource.properties");
Class.getResourceAsStream ("/some/pkg/resource.properties");
ResourceBundle.getBundle ("some.pkg.resource");

How can you do the same using a Spring bean container?

+4  A: 

Your beans.xml file should have a PropertyPlaceholderConfigurer:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
   <property name="locations">
   <list>
     <value>classpath:some/pkg/resource.properties</value>
   </list>
   </property>

   <!-- Default values for backwards compatibility -->
   <property name="properties">
    <props>
     <prop key="name">value</prop>
    </props>
   </property>
  </bean>

And then you can reference the properties as such elsewhere in the beans.xml:

<bean class="${blah}">
    ....
<bean>

For an article about this, check out http://almaer.com/blog/spring-propertyplaceholderconfigurer-a-nice-clean-way-to-share

scompt.com
Unlike the methods to which I refer in my question, function `<util:properties/>`, and class `PropertiesFactoryBean`, the `PropertyPlaceholderConfigurer` approach doesn't make the properties visible outside of the context.
Derek Mahar
+1  A: 

We use this :

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
    <property name="locations">
        <value>classpath:test.properties</value>
    </property>
</bean>

Which allows the properties defined there to be used as references in the config files

For more info see :

http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/beans/factory/config/PropertyPlaceholderConfigurer.html

Peter Tillemans
Unlike the methods to which I refer in my question, function `<util:properties/>`, and class `PropertiesFactoryBean`, the `PropertyPlaceholderConfigurer` approach doesn't make the properties visible outside of the context.
Derek Mahar
+1  A: 

There's this thing called a PropertyPlaceholderConfigurer, you can use it to inject your beans with values from a properties file, like this:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <value>classpath:com/foo/jdbc.properties</value>
    </property>
</bean>

<bean id="dataSource" destroy-method="close"
      class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>
Nathan Hughes
Unlike the methods to which I refer in my question, function `<util:properties/>`, and class `PropertiesFactoryBean`, the `PropertyPlaceholderConfigurer` approach doesn't make the properties visible outside of the context.
Derek Mahar
+1  A: 

For example via the PropertiesFactoryBean. Use the PropertyPlaceholderConfigurer to configure beans in the context via properties.

You will find PropertyPlaceholderConfigurer examples in the other answers. Here is a PropertiesFactoryBean example :

<bean id="properties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="location" value=classpath:config/applicationConfig.properties"/>
</bean>
Timo Westkämper
@Timo: Your answer was the only one to mention both `PropertiesFactoryBean` and `PropertyPlaceholderConfigurer`. Would you care to expand on the differences between these two classes?
Derek Mahar
If you want to inject a Properties instance as a bean then use PropertiesFactoryBean. Use PropertyPlaceholderConfigurer if you want to parametrize other beans based on values of a properties file. I believe ProperiesFactoryBean is what you need here.
Timo Westkämper
@Timo, this is a subtle, yet very important distinction.
Derek Mahar
Yes, they have a different purpose.
Timo Westkämper
+1  A: 

If you want to reference the object as an instance of java.util.Properties, you should do the following:

<bean id="properties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="ignoreResourceNotFound"><value>true</value></property>
    <property name="locations">
        <list>
            <value>classpath:property-file.properties</value>
        </list>
    </property>
</bean>

This allows you to reference the Spring bean properties as an instance of java.util.Properties. You can even have it merge together multiple properties files by adding more values to location. See this description of resource strings for information about what types of values Spring will accept for location. If you are wanting to use ${} style substitutions in the Spring XML, you can see there are a number of other answers describing how to do that.

laz
This solution is closer to the methods to which I refer in my question and behaves similar to function `<util:properties/>`.
Derek Mahar
+4  A: 

The Spring Framework Reference Documentation (2.5.x) gives two examples of how to load a property file into a bean container, one before the release of version 2.5 and a more concise way using the <util:properties/> function that was introduced in version 2.5:

Before version 2.5:

<!-- creates a java.util.Properties instance with values loaded from the supplied location -->
<bean id="jdbcConfiguration" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
  <property name="location" value="classpath:com/foo/jdbc-production.properties"/>
</bean>

After version 2.5:

<!-- creates a java.util.Properties instance with values loaded from the supplied location -->
<util:properties id="jdbcConfiguration" location="classpath:com/foo/jdbc-production.properties"/>

Note that in order to use <util:properties/>, you must declare the util namespace and schema location in the preamble at the top of your Spring XML configuration file:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd"&gt;

<!-- <bean/> definitions here -->

</beans>
Derek Mahar
Looking at the schema and the documentation in appendix A, apparently it does not.
laz