通过接口注入服务类?

5 浏览
0 Comments

通过接口注入服务类?

我有两个实现了相同接口的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的实现。

0
0 Comments

问题的出现原因:当需要在代码中使用接口的多个实现时,需要解决如何将具体的实现注入到代码中的问题。

解决方法:有两种方法可供选择。

第一种方法是使用特定的标识来标识每个实现,然后注入特定的实现。可以通过在每个实现类上使用特定的注解(例如@One和@Two)来标识不同的实现,然后注入相应的实现。例如:

@One
InterfaceOne implementation;

第二种方法是在需要注入的地方使用一个集合来保存所有的实现。这种方法适用于使用策略接口的情况,希望将所有的实现都注入进来。可以使用List或Optional来保存实现的集合。例如,如果期望有1到n个实现,则使用:

List implementations;

如果实现是可选的(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 List 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 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`方法根据用户的语言设置选择一个对应的实现类来打印问候语。

0