Two approaches when dealing with multiple implementations:
Use a specific flavour, identified by a @Qualifier
Annotate each implementation with a specific @Qualifier
(such as @Qualifier("One")
and @Qualifier("Two")
), and inject the specific flavour:
@Autowired
@Qualifier("One")
InterfaceOne implementation;
Use all implementations (or evaluate most appropriate with code)
The second approach is useful when you have a strategy interface, and want to have all implementations injected. You can then use all or any of them, and also query them for additional details.
In that case (when expecting 1..n implementations), use:
@Autowired
List<InterfaceOne> implementations;
If the implementations are optional (0..n), use:
@Autowired
Optional<List<InterfaceOne>> implementations;
EDIT: example on how to use a strategy interface with multiple implementations:
Interface:
public interface HelloWorldService {
String sayHello();
String getLanguage();
}
Implementations:
@Service
public class HelloWorldServiceEN implements HelloWorldService {
public String sayHello() { return "Hi there!"; }
public String getLanguage() { return "en"; }
}
@Service
public class HelloWorldServiceDE implements HelloWorldService {
public String sayHello() { return "Hallo!"; }
public String getLanguage() { return "de"; }
}
@Service
public class HelloWorldServiceFR implements HelloWorldService {
public String sayHello() { return "Salut!"; }
public String getLanguage() { return "fr"; }
}
Usage:
@Autowired
private List<HelloWorldService> helloWorldServices;
public void sayHelloInAllLanguages() {
for (HelloWorldService helloWorldService : helloWorldServices) {
System.out.println(helloWorldService.sayHello());
}
}
public void sayHelloInUserLanguage() {
String userLanguage = Locale.getDefault().getLanguage();
HelloWorldService helloWorldService = find(userLanguage);
System.out.println(helloWorldService.sayHello());
}
private HelloWorldService find(String language) {
// find service in specific language
Optional<HelloWorldService> service = helloWorldServices.stream().filter(s -> language.equals(s.getLanguage())).findFirst();
if (service.isPresent()) {
return service.get();
}
// fallback to english, if available
service = helloWorldServices.stream().filter(s -> language.equals("en")).findFirst();
if (service.isPresent()) {
return service.get();
}
// fallback to any language
return helloWorldServices.stream().findFirst().orElseThrow(IllegalStateException::new);
}