java - 通过接口(interface)注入(inject)服务类?

标签 java spring-boot

所以我有 2 个实现相同接口(interface)的服务类:

@Service
public class ServiceOne implements InterfaceOne {

}

@Service
public class ServiceTwo implements InterfaceOne {

}

我想知道如何在 Controller 内注入(inject)特定实例?

@RestController
@RequestMapping("/test")
public class MyController {
    @Inject
    public MyController(InterfaceOne service) {

    }
}

我不确定 DI 应该如何与服务类一起工作。基本上,这两个服务类具有相同的接口(interface),如果我可以将正确的服务注入(inject)到 Controller 中,我希望避免必要的情况。一个例子将非常感激。

编辑:抱歉各位,我没说清楚。我还需要弄清楚的是,需要将哪个服务类注入(inject)到 Controller 中,而无需指定具体的实现。因此,我希望有一种方法可以执行某种 if 语句并检查应该插入哪个服务实现。

最佳答案

处理多个实现时的两种方法:

使用由@Qualifier标识的特定 flavor

使用特定的@Qualifier注释每个实现(例如@Qualifier("One")@Qualifier("Two") ),并注入(inject)特定的味道:

@Autowired
@Qualifier("One")
InterfaceOne implementation;

使用所有实现(或使用代码评估最合适的实现)

当您有策略接口(interface)并且希望注入(inject)所有实现时,第二种方法非常有用。然后,您可以使用全部或任何它们,还可以查询它们以获取更多详细信息。

在这种情况下(当期望 1..n 实现时),请使用:

@Autowired
List<InterfaceOne> implementations;

如果实现是可选的(0..n),请使用:

@Autowired
Optional<List<InterfaceOne>> implementations;

编辑:如何使用具有多个实现的策略接口(interface)的示例:

界面:

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);
}

关于java - 通过接口(interface)注入(inject)服务类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53297846/

相关文章:

mongodb - Docker的Spring Boot mongo异常

java - 如何以编程方式发现 Spring Boot 使用的 JPA 实现和 SQL 方言?

java - 基于名称的 Spring Javaconfig Autowiring 不起作用

java - 在以下任何来源中均未找到插件 [id : 'org.springframework.boot' , 版本: '2.1.7.RELEASE']

java - 我得到一个 FileNotFoundException 但文件在那里

java - 从 Android Studio 启动应用程序停止工作

spring - 使用 Spring Boot 和 MySQL 保存图像

java - 混淆嵌套泛型的集合

java - 无法为同一切面类的方法设置建议

java - Spring Boot集成XXE预防设置