0

nI am developing a Spring MVC web app using Spring 3.2. We will deploy the web app to different customers. Each customer may use one of several implementations of a service interface.

It's possible that the customer may need to reset these values, so we can't just hard-wire the implementation into the application, it needs to be externally configurable. We are already using customer-specific property files that for setting simple properties such as Strings, numbers etc, but I'm asking how to set a particular implementation of an interface.

E.g.,

class MyClass {
 // this is straightforward
 @Value("${customer.propertyInPropertyFile}")
 private String customerSpecificString;

 // how to set the correct implementation for each customer?
 private ISomeService service;

}

If there are 4 implementations of ISomeService, we can't autowire, or explicitly set a bean, as this will then be set in the compiled code - and it needs to be configurable after the application is deployed ( it would be OK to restart the application though if need be)..

Does anyone know how to do this? Would this better be performed using Spring EL, or profiles?

Thanks!

otter606
  • 335
  • 1
  • 4
  • 21
  • possible duplicate of [Spring Qualifier and property placeholder](http://stackoverflow.com/questions/7812745/spring-qualifier-and-property-placeholder) – Hamid Samani Sep 11 '14 at 20:28
  • also take a look at [spring profiles](https://spring.io/blog/2011/02/14/spring-3-1-m1-introducing-profile/). – Hamid Samani Sep 11 '14 at 21:16
  • I had a look at the first link, this is using aliases and XML configuration. I was hoping to use Java annotation configuration but perhaps this is impossible since annotation values are compile-time constants. Things are complicated by the fact that in our Spring config file, the same ${} notation also identifies variables replaced during Maven build, so will need to figure out how to distinguish properties that are replaced at compile time ad build time. – otter606 Sep 11 '14 at 22:33

1 Answers1

-1

So, as I wanted to used Java configuration, I used the following solution:

@Configuration
@Profile("prod")
@EnableAsync
public class ProductionConfig extends BaseConfig
// inject property value which identifies theimplementation to use
Value("${service.impl}")
private String serviceName;

@Bean()

    public IRepository repository() {
        IRepository rc = null;
        if(StringUtils.isEmpty(serviceName)){
            rc =  new Impl1();
        } else if ("sword-mets".equals(serviceName)){
            rc = new Impl2();
        } else {
            rc = new Impl3();
        }
        log.info("Setting in repository implementation " + rc);
        return rc;

    }

So, this isn't quite as clean as the suggested reply using aliases - the Config class needs to know about all the possible implementation classes - but is simple and avoids having to use the XML config just for this bean.

otter606
  • 335
  • 1
  • 4
  • 21
  • when you create objects explicitly using new keyword instead of beanfactory the wiring inside those objects will not happen. – krishna T Mar 04 '22 at 08:52