所以我有2个实现相同接口的Service类:
@Service
public class ServiceOne implements InterfaceOne {
}
@Service
public class ServiceTwo implements InterfaceOne {
}
我想知道如何在控制器内注入特定实例?
@RestController
@RequestMapping("/test")
public class MyController {
@Inject
public MyController(InterfaceOne service) {
}
}
我不确定DI应该如何与服务类一起使用。基本上,这两个服务类具有相同的接口,如果可以将正确的一个注入到控制器中,我希望避免不必要的情况。一个例子将不胜感激。
编辑:抱歉,我不清楚。我还需要弄清楚的是,需要在控制器中注入哪种服务类,而无需在此时指定具体实现。因此,我希望有一种方法可以执行某种if语句,并检查应插入该服务的哪种实现。
答案 0 :(得分:1)
处理多种实现时的两种方法:
使用由@Qualifier
用特定的@Qualifier
(例如@Qualifier("One")
和@Qualifier("Two")
注释每个实现,并注入特定的风味:
@Autowired
@Qualifier("One")
InterfaceOne implementation;
使用所有实现(或使用代码评估最合适的实现)
当您有一个策略接口并想注入所有实现时,第二种方法很有用。然后,您可以使用全部或任何一个,还可以查询它们以获取其他详细信息。
在这种情况下(当需要1..n实现时),请使用:
@Autowired
List<InterfaceOne> implementations;
如果实现是可选的(0..n),请使用:
@Autowired
Optional<List<InterfaceOne>> implementations;
EDIT:有关如何在多个实现中使用策略界面的示例:
接口:
public interface HelloWorldService {
String sayHello();
String getLanguage();
}
实施:
@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"; }
}
用法:
@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);
}