Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring 3.1 Environment does not work with user property files

Tags:

java

spring

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.

like image 673
endless Avatar asked Jan 05 '13 07:01

endless


People also ask

How do I get environment property in Spring boot?

Environment-Specific Properties File. If we need to target different environments, there's a built-in mechanism for that in Boot. We can simply define an application-environment. properties file in the src/main/resources directory, and then set a Spring profile with the same environment name.

What is properties file in Spring?

So in a spring boot application, application. properties file is used to write the application-related property into that file. This file contains the different configuration which is required to run the application in a different environment, and each environment will have a different property defined by it.


3 Answers

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/

like image 134
Boris Treukhov Avatar answered Nov 15 '22 17:11

Boris Treukhov


Adding local properties to PropertySourcesPlaceholderConfigurer (with setProperties() or setLocation()) doesn't make them available in the Environment.

Actually it works in the opposite way - Environment acts as a primary source of properties (see ConfigurableEnvironment), and PropertySourcesPlaceholderConfigurer can make properties from the Environment available using ${...} syntax.

like image 33
axtavt Avatar answered Nov 15 '22 17:11

axtavt


I did this per @Boris suggestion..

    PropertySourcesPlaceholderConfigurer propertyHolder = new PropertySourcesPlaceholderConfigurer();
    ConfigurableEnvironment env = new StandardEnvironment();
    env.getPropertySources().addFirst(
            new ResourcePropertySource(new ClassPathResource(
                    "SpringConfig.properties")));
    propertyHolder.setEnvironment(env);
    context.addBeanFactoryPostProcessor(propertyHolder);
            context.register(SpringConfig.class);
            context.refresh();

Now in @Configuration classes all properties (including my own and system properties) can be resolved using @Value.

But the Environment that gets @Autowired into @Configuration class has only system properties in it, not SpringConfig.properties I set as above. But clearly, before calling context.refresh() above, the ConfigurableEnvironment has my properties also. But once context.refresh() is called, my properties are removed from the Environment that gets autowired into @Configuration.

I want to be able to use the better syntax, env.getProperty("my.property"). Does anybody know why that is the case?

like image 32
endless Avatar answered Nov 15 '22 16:11

endless