Given two (or more) implementations of a particular service API, what's the best way to pick which one to use at runtime in my app based on an application property?
Example API:
public interface Greeting {
String sayHello(String username);
}
Implementations:
public class FriendlyGreeting implements Greeting {
public String sayHello(String username) {
return "Hello, " + username;
}
}
public class HostileGreeting implements Greeting {
public String sayHello(String username) {
return "Go away, " + username;
}
}
I've got a separate service class with an @Autowired
constructor that takes an instance of Greeting
. What I want, is based upon a configuration property, to decide which greeting implementation gets injected and used. I came up with using a configuration class to make that decision:
@Configuration
public class GreetingConfiguration {
private String selection;
@Autowired
public GreetingConfiguration(@Value("${greeting.type}") String type) {
this.selection = type;
}
@Bean
public Greeting provideGreeting() {
if ("friendly".equals(selection)) {
return new FriendlyGreeting();
} else {
return new HostileGreeting();
}
}
}
Is this the right way to do what I want? I went down the road of using @Qualifier
on the implementations, and ended up with a mess where Spring saw 3 instances of my Greeting
API, and I needed a configuration anyway to pick which implementation to use and return it with a unique qualifier name on it, and that feels worse than what I settled on.