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.
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.
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.
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/
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.
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With