3

My controller:

@RestController
@RequestMapping("/mypath")
public class MyController {
   @Autowired
   MyServiceInterface service;

   @PostMapping("/{source}")
   void myControllerFunc(@PathVariable String source, @RequestBody MyObject obj) {
       ...
       Object myServiceObj = service.myServiceFunc(param);
       ...
   }
}

My Service Interface:

public interface MyServiceInterface {

   Object myServiceFunc(String param);

}

My Service Implemantations:

@Service    
public class MyServiceOne {

   Object myServiceFunc(String param) {
       ...
   }

}

@Service
public class MyServiceTwo {

   void myServiceFunc(String param) {
       ...
   }

}

My spring-boot version : 1.5.7

I want to inject the service according to my path variable ("source") . If source = one, inject MyServiceOne or if source = two, inject MyServiceTwo.

Is this possible?

cguzel
  • 1,673
  • 2
  • 19
  • 34

3 Answers3

2

It sounds like you need both of these to be available and each method invocation on the controller can choose a different one. So wire up both implementations, with a qualifier to distinguish them. Use the path variable in the controller method and let it decide programmatically which service to call.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
1

I don't think it's possible and reasonable.

A @RestControllers is by nature a singleton. It gets configured at startup and remains the same for every request.

The expression /{source} is being evaluated during a request at runtime, when the controller has already been set up.

The options to consider:

  1. Inject both services and, in the method, decide which one to pick.
  2. Create two separate controllers for each service.
  3. Utilise the application context and extract beans from there.
Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
0

As described in Get bean from ApplicationContext by qualifier, you could add qualifiers to each service implementations and have something like this in the myControllerFunc:

BeanFactoryAnnotationUtils.qualifiedBeanOfType(ctx.getBeanFactory(), MyServiceInterface.class, source)
lealceldeiro
  • 14,342
  • 6
  • 49
  • 80
GriffoGoes
  • 715
  • 7
  • 17