代码之家  ›  专栏  ›  技术社区  ›  Zed

通过接口注入服务类?

  •  0
  • Zed  · 技术社区  · 7 年前

    @Service
    public class ServiceOne implements InterfaceOne {
    
    }
    
    @Service
    public class ServiceTwo implements InterfaceOne {
    
    }
    

    我想知道如何在控制器中注入特定的实例?

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

    我不确定DI应该如何处理服务类。基本上,这两个服务类具有相同的接口,如果我能将正确的接口注入控制器,我希望避免Nessery。请举个例子。

    1 回复  |  直到 7 年前
        1
  •  3
  •   Peter Walser    7 年前

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

    使用特定的味道,通过 @Qualifier

    用特定的 @限定符 (例如 @Qualifier("One") @Qualifier("Two") ),并注入特定风味:

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

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

    当您有一个策略接口,并且希望注入所有实现时,第二种方法很有用。然后,您可以使用所有或其中任何一个,还可以查询它们以获取其他详细信息。

    @Autowired
    List<InterfaceOne> implementations;
    

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

    @Autowired
    Optional<List<InterfaceOne>> implementations;
    

    接口:

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