Thursday, January 24, 2013

Spring 3.1 registering and using properties

Registering properties in Spring 

Starting with Spring 3.1, the new Environment and PropertySource abstractions simplify working with properties. The default Spring Environment now contains two property sources: the System properties and the JVM properties, with the System properties having precedence.

(1) Registering Properties via the XML namespace:
  <context:property-placeholder location="classpath:config/${env:local}/**/*.properties" ignore-unresolvable="true"/>  

(2) Registering Properties via Java Annotation:(2) 
 @PropertySource("classpath:config/${env:local}/environment.properties")  

Spring 3.1 introduces the new @PropertySource annotation, as a convenient mechanism of adding property sources to the environment. But as opposed to using XML namespace element, the Java @PropertySource annotation does not automatically register a PropertySourcesPlaceholderConfigurer with Spring.

Instead, the bean must be explicitly defined in the configuration to get the property resolution mechanism working.
   @Bean  
   public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {  
   return new PropertySourcesPlaceholderConfigurer();  
   }  

Note: Resource location wildcards (e.g. **/*.properties) are not permitted; each location must evaluate to exactly one .properties resource.  So if you want to use wildcards in your propertySource, don't  use Method 2).

(3)  Registering Properties via Java configuration:
   static @Bean public PropertySourcesPlaceholderConfigurer myPropertySourcesPlaceholderConfigurer() throws IOException {  
     String envVar = System.getenv("env");   
     if (envVar == null)   
       envVar = "local";  
     PropertySourcesPlaceholderConfigurer p = new PropertySourcesPlaceholderConfigurer();  
     p.setLocations(new PathMatchingResourcePatternResolver()  
             .getResources("classpath*:config/"+envVar+"/*.properties"));  
     p.setIgnoreUnresolvablePlaceholders(true);  
     return p;  
   }  

Using properties in Spring 

 Both the older PropertyPlaceholderConfigurer and the new PropertySourcesPlaceholderConfigurer added in Spring 3.1 resolve ${…} placeholders within bean definition property values and @Value annotations.

For example, to inject a property using the @Value annotation:
 @Value( "${jdbc.url}" )  
 private String jdbcUrl;  

Using properties in Spring XML configuration:
 <bean id="dataSource">  
  <property name="url" value="${jdbc.url}" />  
 </bean>  

And lastly, obtaining properties via the new Environment APIs:
 @Autowired  
 private Environment env;  
 ...  
 dataSource.setUrl(env.getProperty("jdbc.url"));  




2 comments:

  1. I register my properties file via xml configuration using context:property-placeholder. When I try to access the properties via env.getProperty it always returns null but @Value and ${...} in xml bean definitions resolve just fine. It looks like PropertySourcesPlaceholderConfigurer does not register its property sources with environments.

    In your example above I wonder how you got it working with env.getProperty().

    Thanks,

    ReplyDelete