2

Background: I am writing a library that will be compiled into a JAR file. That library will be used as a dependency in a number of web applications. Both the library and the web apps are using Spring. There is an onus on the web application to run a ComponentScan on the library classes to pick up any Spring Beans / configuration.

Ask: Within the library I want to load properties from a property file using PropertySourcesPlaceholderConfigurer. Something like this:

package com.blah;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;

@Configuration
@PropertySource("classpath:properties/blah.${environment}.properties")
public class AppConfig {

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

This is working fine.

Question: if the web-app that loads this library as a dependency also uses PropertySourcesPlaceholderConfigurer to load properties, will there be a conflict between the two? Will one override the other (even if the properties are different)? Or can they live in peaceful harmony side-by-side?

Using Spring 3.2.4


UPDATE As per Bogdan Oros's answer below, it looks like this is OK i.e. they will not conflict and both sets of properties will be loaded. I created two Config files:

@Configuration
@PropertySource("classpath:properties/blah.stage1.properties")
public class BlahClientConfig1 {

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

and

@Configuration
@PropertySource("classpath:properties/blah.stage2.properties")
public class BlahClientConfig2 {

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

When I run my tests, I can successfully retrieve property values from both blah.stage1.properties and blah.stage2.properties

CodeClimber
  • 4,584
  • 8
  • 46
  • 55

1 Answers1

2

You can do an experiment a create same bean in two different configurations in same classpath and it will work

@Configuration
class AConfiguration {
    @Bean
    public static PropertySourcesPlaceholderConfigurer resolver() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

@Configuration
class B {|
    @Bean
    public static PropertySourcesPlaceholderConfigurer resolver() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

It will work correctly because spring resolves such situations. You'll find that one bean is overridden by the other. But if you will help spring and setup names explicitly

@Configuration
class A {
    @Bean(name="resolver")
    public static PropertySourcesPlaceholderConfigurer resolver() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

@Configuration
class B {
    @Bean(name="resolver")
    public static PropertySourcesPlaceholderConfigurer resolver() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

This situation will cause a injection failure, because it cannot decide which bean to inject. It is explained here and also it can be configured with DefaultListableBeanFactory. Check this answer.

Bogdan Oros
  • 1,249
  • 9
  • 13