Announcement Announcement Module
No announcement yet.
adding PropertySources to Environment - how to ensure refresh() called after? Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • adding PropertySources to Environment - how to ensure refresh() called after?

    I have a Properties object that I'd like add as PropertySource to be used in interpolation throughout my app. ie in any bean within my app I would like to be able to do this:
    ctx.getEnvironment.resolvePlaceholders("${myProp}); //myProp is in the above Properties object
    From Environment JavaDoc:
    When an Environment is being used by an ApplicationContext, it is important that any such PropertySource manipulations be performed before the context's refresh() method is called.
    How can the above be accomplished? - within WebApp contexts but also within unit-test env?

    I tried creating a bean that would add PropertySource and calling ctx.refresh() but a unit test with config below seems to use GenericXmlApplicationContext which does not support (repeat) calls to refresh()

  • #2
    I am not sure I am clear on what you are trying to accomplish. But if you add a PropertySource to the PropertySourcesPlaceholderConfigurer you can access those properties through Spring's Environment. If you want refreshable properties take a look at ReloadableResourceBundleMessageSource.


    • #3
      Profiles with properties files

      I really don't now if is this user case apply, but I saw a lot of people with the some problem: how to set a active profile without messing with bash variables or java
      The most common case: you have a "jndi" connection to your database in your production code, but the integration tests runs with a local driver.
      Until now (Spring 3.1) you have a lot of xml files and with some profiles in Maven (don't confuse them with Spring profiles) you copy the desired one to the default if you are in production, or in dev, etc.
      When I read about profiles in Spring I thought that mess is over. A simple property file with my active profile et voilá. Well not so fast.

      A sample test file with context in @Configuration classes
      @ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = {MongoTemplateConfig.class, LazVirtualMongoConfig.class, ProductionMongoConfig.class})
      public class MongoTest {
          private MongoTemplate mongoTemplate;
          public void crudTest() {
      The configuration classes
      public class LazVirtualMongoConfig implements MongoConfig {
          public @Bean
          MongoFactoryBean mongo() {
              MongoFactoryBean mongo = new MongoFactoryBean();
              return mongo;
      are annotated with different profiles and everything works fine if I put the @ActiveProfile("dev") or @ActiveProfile("prd") in the test class.

      But that gives me again a hard coded configuration!
      What I need is the possibility of reading a external property file and set my active profile before the AnnotationConfigContextLoader registries the configuration classes.
      After reading everything Google gives me about the subject I find the solution in... the javadoc of AbstractGenericContextLoader:
      	 * Prepare the {@link GenericApplicationContext} created by this<code>ContextLoader</code>.
      	 * Called <i>before</i> bean definitions are read.
      	 * <p>The default implementation is empty. Can be overridden in subclasses to
      	 * customize <code>GenericApplicationContext</code>'s standard settings.
      	 * @param context the context that should be prepared
      	 * @see #loadContext(MergedContextConfiguration)
      	 * @see #loadContext(String...)
      	 * @see GenericApplicationContext#setAllowBeanDefinitionOverriding
      	 * @see GenericApplicationContext#setResourceLoader
      	 * @see GenericApplicationContext#setId
      	 * @since 2.5
      	protected void prepareContext(GenericApplicationContext context) {
      The AnnotationConfigContextLoader extends this class and mine become:

      public class MyAnnotationConfigContextLoader extends AnnotationConfigContextLoader{
          protected void prepareContext(GenericApplicationContext context){
              try {
                  context.getEnvironment().getPropertySources().addFirst(new ResourcePropertySource(""));
              } catch (IOException ex) {
      And it works like a champion.
      The only thing we have to do is change the annotation to
      @ContextConfiguration(loader = MyAnnotationConfigContextLoader.class, classes = {MongoTemplateConfig.class, LazVirtualMongoConfig.class, ProductionMongoConfig.class})
      If someone has a better aproach....
      Last edited by fsoares; Feb 28th, 2012, 07:46 AM.