Categories
java spring

Spring 3.1 Environment does not work with user property files

I am doing this..

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(context);
xmlReader
.loadBeanDefinitions(new ClassPathResource("SpringConfig.xml"));
PropertySourcesPlaceholderConfigurer propertyHolder = new PropertySourcesPlaceholderConfigurer();
propertyHolder.setLocation(new ClassPathResource(
"SpringConfig.properties"));
context.addBeanFactoryPostProcessor(propertyHolder);
......
context.refresh();

Now in my @Configuration files, the properties present in my SpringConfig.properties are not getting picked up if I do this…

@Autowired
private Environment env
.....
env.getProperty("my.property")

But I get that property if I use

@Value("${my.property}")
private String myProperty;

I even tried adding couple of more lines like this, but of no use.

ConfigurableEnvironment env = new StandardEnvironment();
propertyHolder.setEnvironment(env);

Does anybody know why my properties are not loaded into Environment? Thanks.

PropertySourcesPlaceholderConfigurer reads property files directly(as it was done by PropertyPlaceholderConfigurer in Spring 3.0 times), it’s just a postprocessor which does not change the way properties are used in the Spring context – in this case properties are only available as bean definition placeholders.

It’s the PropertySourcesPlaceholderConfigurer who uses Environment and not vice versa.

Property sources framework works on the application context level, while property placeholder configurers only provide the functionality to process placeholders in the bean definitions. To use property source abstraction you should use @PropertySource annotation i.e. decorate your configuration class with something like
@PropertySource("classpath:SpringConfig.properties")

I believe that you can do the same thing programmatically, i.e. you can get the container’s ConfigurableEnvironment before the context was refreshed, modify its MutablePropertySources(you need first to get AbstractApplicationContext environment property via context.getEnvironment() ) via getPropertySources().addFirst(new ResourcePropertySource(new ClassPathResource(
"SpringConfig.properties")));
but it’s unlikely what you want to do – if you already have a @Configuration annotated class, decorating it with @PropertySource("classpath:SpringConfig.properties") is much simpler.

As for the PropertySourcesPlaceholderConfigurer instance – it will fetch property sources automatically(as it implements EnvironmentAware) from its application context so you need just to register a default instance of it.

For the examples of custom property source implementation see http://blog.springsource.org/2011/02/15/spring-3-1-m1-unified-property-management/