Java 在一个类字段中处理一个Springbean/接口的多个实现

Java 在一个类字段中处理一个Springbean/接口的多个实现,java,spring,spring-boot,Java,Spring,Spring Boot,与此类似,但我有这种情况。假设我有一个AccountService接口和两个实现:DefaultAccountServiceImpl和SpecializedAccountServiceImpl,这些类与前面的类一样。实现在一个类中,但是对于不同的方法有不同的bean实现。说: @RestController @RequestMapping("/account") public class AccountManagerRestController { @Autowired pri

与此类似,但我有这种情况。假设我有一个
AccountService
接口和两个实现:
DefaultAccountServiceImpl
SpecializedAccountServiceImpl
,这些类与前面的类一样。实现在一个类中,但是对于不同的方法有不同的bean实现。说:

@RestController
@RequestMapping("/account")
public class AccountManagerRestController {

    @Autowired
    private AccountService service;

    @RequestMapping(value = "/register", method = RequestMethod.POST)
    HttpEntity<?> registerAccount(@RequestBody AccountRegisterRequestBody input) {
        // here the `service` is DefaultAccountServiceImpl
        ...
    }


    @RequestMapping(value = "/register/specialized", method = RequestMethod.POST)
    HttpEntity<?> registerSpecializedAccount(@RequestBody AccountRegisterRequestBody input) {
        // here the `service` is SpecializedAccountServiceImpl
        ...
    }
}
@RestController
@请求映射(“/account”)
公共类AccountManagerRestController{
@自动连线
私人帐户服务;
@RequestMapping(value=“/register”,method=RequestMethod.POST)
HttpEntity registerAccount(@RequestBody AccountRegisterRequestBody input){
//这里的'service'是DefaultAccountServiceImpl
...
}
@RequestMapping(value=“/register/specialized”,method=RequestMethod.POST)
HttpEntity注册表SpecializedAccount(@RequestBody AccountRegisterRequestBody输入){
//这里的“服务”是专门化的AccountServiceImpl
...
}
}
使用
@限定符(“beanName”)


我真的不明白其中的区别。在本例中,您只需创建两个不同的bean,然后使用不同的
@限定符对它们进行注释

但是,如果你没有得到它,以下是你可以实现它的方法:

@RestController
@RequestMapping("/account")
public class AccountManagerRestController {

    @Autowired
    @Qualifier("DefaultAccountServiceImpl")
    private AccountService serviceDAS;

    @Autowired
    @Qualifier("SpecializedAccountServiceImpl")
    private AccountService serviceSAS;

    @RequestMapping(value = "/register", method = RequestMethod.POST)
    HttpEntity<?> registerAccount(@RequestBody AccountRegisterRequestBody input) {
        /* Use ServiceDAS Here */
        ...
    }

    @RequestMapping(value = "/register/specialized", method = RequestMethod.POST)
    HttpEntity<?> registerSpecializedAccount(@RequestBody AccountRegisterRequestBody input) {
        /* Use ServiceSAS Here */
        ...
    }
}

我更喜欢这种方法,因为我不必使用两个注释。

对于一些实现,比如1或2个,使用@Qualifier符号就足够了,但是在实现将随时间增长的情况下,更具可扩展性的解决方案将是利用工厂模式

因此,根据传入的实现参数,只有factory类负责获取实现。因此
服务1实现可以通过将“SERVICE1”作为字符串传递给工厂类来触发,工厂类将以这种方式返回服务1。

演示如何将两个不同的实现自动连接到一个类中。只需在第一个方法中使用非专门化的实现,在第二个方法中使用专门化的实现,区别是什么?您只需创建AccountService的两个不同bean,并分别用
@Qualifier(“DefaultAccountServiceImplBeanName”)
@Qualifier(“SpecializedAccountServiceImplBeanName”)
对它们进行注释。因此,它不能分配给一个字段?@Morilla不,您不能!Spring如何知道您试图访问哪个实现?@user2004685,可能通过注释方法并在其上传递限定符名称。如果存在这样的功能,那么不能将其分配给一个字段?如果几个方法(而不仅仅是两个)有不同的实现呢?如果你说同一个接口有两个以上的实现,那么是的,你必须为每个实现注入相同类的bean数量。如果我有两个以上呢?说10。我也必须声明10个字段?@Morillataisa那么你有一个相当严重的设计错误,应该找到一个合理的方法来处理它,比如服务注册。你有一些关于“服务器注册”的文档吗?如何使用Spring实现,我想我也有同样的设计问题。
@RestController
@RequestMapping("/account")
public class AccountManagerRestController {

    @Autowired
    @Qualifier("DefaultAccountServiceImpl")
    private AccountService serviceDAS;

    @Autowired
    @Qualifier("SpecializedAccountServiceImpl")
    private AccountService serviceSAS;

    @RequestMapping(value = "/register", method = RequestMethod.POST)
    HttpEntity<?> registerAccount(@RequestBody AccountRegisterRequestBody input) {
        /* Use ServiceDAS Here */
        ...
    }

    @RequestMapping(value = "/register/specialized", method = RequestMethod.POST)
    HttpEntity<?> registerSpecializedAccount(@RequestBody AccountRegisterRequestBody input) {
        /* Use ServiceSAS Here */
        ...
    }
}
@Resource(name = "DefaultAccountServiceImpl")
private AccountService serviceDAS;

@Resource(name = "SpecializedAccountServiceImpl")
private AccountService serviceSAS;