Spring switch implementations based on a runtime condition

Viewed 4315

This is a simplified version of what I am trying to achieve. I have multiple implementations of the same interface. Based on the user input at runtime I want to pick the correct implementation.

For example suppose I an interface called Color. There are many classes that implement this interface, the Red class, the Blue class, the Green class and so on.

At run time I need to pick implementations based on the user input. One way to achieve this would be something like this

 @Autowired
 @Qualifier("Red")
 private Color redColor;

 @Autowired
 @Qualifier("Green")
 private Color greenColor;


private Color getColorImplementation()
{
if(userInput=="red")
{
return redColor;

}
else if(userInput=="green")
{
return greenColor;
}
else
{
return null;
}

}

But the problem with this is that everytime a new implementation is added, I would have to update the code that picks the implementation, which beats the whole purpose of inversion of control part of spring. What is the right way to do this using spring?

4 Answers

Same issue happen in my implementation where in, the scenario was based on user input, where the respective interface implementation needs to be invoked.

This solve my problem:

        **Base Interface**
        @Service
        public interface ParentInterface {
                public String doThis(ClassA param);
        }

        **First Implementation**

        @Component("FirstImp")
        public class FirstServiceImp implements ParentInterface {
        public String doThis(ClassA param){

        }
        **Second Implementation**

        @Component("SecondImp")
        public class SecondServiceImp implements ParentInterface {
        public String doThis(ClassA param){

        }

        **Factory**
        @Service
        public class ServiceResolver {

        @Autowired
        @Qualifier("FirstImp")
        private ParentInterface firstImpl;

        @Autowired
        @Qualifier("SecondImp")
        private ParentInterface secondImpl;

        public ParentInterface getInstance(String condition){
            switch(condition) {
            case "X": return firstImpl;
            case "Y": return secondImpl;
            default:
                throw new IllegalArgumentException(condition);
        }
        }
        }
        **Controller**
        @RestController
        public class UserController {
        @Resource
        private ServiceResolver serviceresolver;

        @PostMapping("/userbase/{inp1}/messages/{inptype}")
        public ResponseEntity<String> sendData(@PathVariable String 
        inp1,@PathVariable String inptype, @RequestBody XYZBean msg) 
        {
        for(ABC data : msg.getSubData())
            serviceresolver.getInstance(data.getType()).doThis(msg);
         return new ResponseEntity<String>("created",HttpStatus.OK);
        }

        }
Related