通过接口注入服务类?
通过接口注入服务类?
我有两个实现了相同接口的Service类:
@Service public class ServiceOne implements InterfaceOne { } @Service public class ServiceTwo implements InterfaceOne { }
我想知道如何在控制器中注入特定的实例?
@RestController @RequestMapping("/test") public class MyController { @Inject public MyController(InterfaceOne service) { } }
我不确定依赖注入如何与service类一起使用。基本上这两个service类都有相同的接口,我希望能够避免不必要的if判断,如果可以直接将正确的service类注入到控制器中就好了。如果有示例会更好。编辑:抱歉,我没有说清楚。我还需要弄清楚的是,在不指定具体实现的情况下,需要在控制器中注入哪个service类。所以,我希望能够进行某种if语句,并检查应该插入哪个service的实现。
问题的出现原因:当需要在代码中使用接口的多个实现时,需要解决如何将具体的实现注入到代码中的问题。
解决方法:有两种方法可供选择。
第一种方法是使用特定的标识来标识每个实现,然后注入特定的实现。可以通过在每个实现类上使用特定的注解(例如@One和@Two)来标识不同的实现,然后注入相应的实现。例如:
@One InterfaceOne implementation;
第二种方法是在需要注入的地方使用一个集合来保存所有的实现。这种方法适用于使用策略接口的情况,希望将所有的实现都注入进来。可以使用List或Optional来保存实现的集合。例如,如果期望有1到n个实现,则使用:
Listimplementations;
如果实现是可选的(0到n个),则使用:
Optional> implementations;
下面是一个使用策略接口和多个实现的示例:
接口:
public interface HelloWorldService { String sayHello(); String getLanguage(); }
实现类:
public class HelloWorldServiceEN implements HelloWorldService { public String sayHello() { return "Hi there!"; } public String getLanguage() { return "en"; } } public class HelloWorldServiceDE implements HelloWorldService { public String sayHello() { return "Hallo!"; } public String getLanguage() { return "de"; } } public class HelloWorldServiceFR implements HelloWorldService { public String sayHello() { return "Salut!"; } public String getLanguage() { return "fr"; } }
使用示例:
private ListhelloWorldServices; 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 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); }
在上面的示例中,我们可以通过调用`sayHelloInAllLanguages`方法来打印出所有实现类的问候语。而`sayHelloInUserLanguage`方法根据用户的语言设置选择一个对应的实现类来打印问候语。