0

I have an application that can use two implementations of a service:

package test;

public interface MyService {
    void doSomething();
}


package test;

public class MyServiceA implements MyService {

    private final String whatever;

    public MyServiceA(final String whatever) {
        this.whatever = whatever;
    }

    @Override
    public void doSomething() {
        System.out.println("MyServiceA did "+whatever);
    }
}


package test;

public class MyServiceB implements MyService {

    private final String what;

    public MyServiceB(final String what) {
       this.what = what;
    }

    @Override
    public void doSomething() {
        System.out.println("MyServiceB did "+what);
    }
}

with different configurations.

I want to select what implementation to use with a system property.

I want to have the configuration for each implementation in its own property file and also its own spring configuration. So I can remove all the non used configuration altogether when not in use.

How may I configure any of the two implementations without requiring the property file of the non configured implementation?

Other solutions to this problem welcome.

John Smith
  • 49
  • 9

3 Answers3

1

You may use profiles and different @Configuration classes for different profiles. http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-definition-profiles-java

Yuri Plevako
  • 311
  • 1
  • 6
  • Actually you may configure it in your web.xml or WebApplicationInitializer, not system property. Changing one row in web.xml is not really a hardcore way. And if you don't want to provide another configuration for another service why do you need property? Actually when you switch profile spring will not even create a @Configuration class bean for non-active profile, so you don't need any properties for it and it will just stay calm in it's package) – Yuri Plevako Sep 20 '16 at 06:35
  • And since you want different property files for different beans you may declare alternative PropertyPlaceHolderConfigurer bean and set a prefix to it's properties. And then you may use prefixed properties for your alternative bean – Yuri Plevako Sep 20 '16 at 06:35
  • I am not supposed to modify the war application, so I cannot change the web.xml file. I can only configure it externally. – John Smith Sep 23 '16 at 20:28
0

This can be achieved via @Qualifier. Here is the link that can provide you the implementation approach you are looking for. Spring Qualifier and property placeholder

Community
  • 1
  • 1
mhasan
  • 3,703
  • 1
  • 18
  • 37
0

I decided to implement it as: https://stackoverflow.com/a/3036044/5759622

These are the required spring XML files:

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <import resource="MyService-${MyService}.xml"/>

</beans>

MyService-MyServiceA.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:property-placeholder location="classpath:test/MyServiceA.properties" />

    <bean class="test.MyServiceA">
        <constructor-arg value="${MyServiceA.whatever}"/>
    </bean>

</beans>

MyService-MyServiceB.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:property-placeholder location="classpath:test/MyServiceB.properties" />

    <bean class="test.MyServiceB">
        <constructor-arg value="${MyServiceB.what}"/>
    </bean>

</beans>
Community
  • 1
  • 1
John Smith
  • 49
  • 9