通过接口注入服务类?

时间:2018-11-14 10:20:06

标签: java spring-boot

所以我有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语句,并检查应插入该服务的哪种实现。

1 个答案:

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