cguzel
cguzel

Reputation: 1735

Dependency injection according to conditions

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?

Upvotes: 3

Views: 106

Answers (3)

Nathan Hughes
Nathan Hughes

Reputation: 96385

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.

Upvotes: 2

Andrew
Andrew

Reputation: 49606

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.

Upvotes: 1

GriffoGoes
GriffoGoes

Reputation: 724

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)

Upvotes: 0

Related Questions