Morilla Thaisa
Morilla Thaisa

Reputation: 121

Handling several implementations of one Spring bean/interface in one class field

Similar to this question, but I have this situation. Suppose I have one AccountService interface and two implementations: DefaultAccountServiceImpl and SpecializedAccountServiceImpl, (the classes just like in the previous question). The implementation is in one class, but has different bean implementation for different method. Say:

@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
        ...
    }
}

Upvotes: 4

Views: 10742

Answers (3)

Rbk
Rbk

Reputation: 72

For a few implementation, say 1 or two, using the @Qualifier notation is enough, but in the instance that the implementation will grow over time, a more scalable solution will be to utilize the factory pattern.

As such, only the factory class will be responsible for fetching the implementation depending on the implementation argument passed in. Thus, Service 1 implementation could be triggered by passing in "SERVICE1" as a string to the factory class which will return service 1in that manner.

Upvotes: 0

ninja.coder
ninja.coder

Reputation: 9648

I don't really understand the difference. You just have to create two different beans in this case and then annotate them with different @Qualifier.

Still if you do not get it, here is how you can achieve it:

@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 */
        ...
    }
}

Alternatively, you can replace the two annotations with one @Resource annotation like this:

@Resource(name = "DefaultAccountServiceImpl")
private AccountService serviceDAS;

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

I prefer this approach as I do not have to use two annotations.

Upvotes: 0

bilal bilal
bilal bilal

Reputation: 124

Use @Qualifier("beanName")

@Autowired @Qualifier("service1")
private AccountService service1;

@Autowired @Qualifier("service2")
private AccountService service2;

Upvotes: 6

Related Questions