1
  1. I have two controllers (ControllerA and ControllerB)

  2. Both controllers call to a service (MyService).

  3. MyService calls to an interface called MyRepository which has two implementations (FirstRepository and SecondRepository).

How is possible to use FirstRepository when the service (MyService) is called from ControllerA and use SecondRepository when the call comes from ControllerB?

This way I can reuse MyService and which repository is used comes from Spring Configuration.

alxsimo
  • 567
  • 1
  • 6
  • 19
  • Conceptionally you have two services, not one. Have a base (possibly abstract) class MyService and two subclasses MyService1 and MyService2 which autowire FirstRepository and SecondRepository respectively. And these services are autowired into ControllerA and B respectively. – RoToRa Mar 09 '20 at 14:53

3 Answers3

1

I can see two possible solutions here. 1. In you MyService class autowire both implementations with @Qualifier annotation (you can also autowire List. Then MyService method would have a parameter saying which MyRepository implementation should be called. I would not recommend this solution. 2. Define two implementations of MyService (FirstService, SecondService). Then FirstService would autowire FirstRepository and SecondService would autowire SecondRepository (use @Qualifier annotation again. Now you can easily inject FirstService to ControllerA and SecondService to ControllerB.

But first I would think about architecture. Maybe you don't need separate controllers?

standy
  • 398
  • 1
  • 3
  • 16
0

Have you checked @Primary or @Resource or @Qualifier annotations? Based on your requirement you can choose out of them.

Something similar has been discussed here.

Sariq Shaikh
  • 940
  • 8
  • 29
0

I ended up creating two controllers and defining two @Configuration classes, one for each @Controller.

And using the @Qualifier annotations defined two sets of beans, and then in each controller let Spring know which @Qualified bean I want injected.

@RestController
@RequestMapping("/v1/inapp/purchases")
class AController(
  @Qualifier("appStore") private val redeemPurchaseService: RedeemPurchaseService
) : RedeemPurchaseApiDocumentation { // More code }

And the other controller

@RestController
@RequestMapping("/v1/inapp/purchases")
class GPlayRedeemPurchaseController(
  @Qualifier("gplay") private val redeemPurchaseService: RedeemPurchaseService
) : RedeemPurchaseApiDocumentation { // More code }

And two @Configuration files, one per controller.

alxsimo
  • 567
  • 1
  • 6
  • 19