MarioC
MarioC

Reputation: 3228

Spring - Autowire multiple Service class from the same Abstract Class

I'm trying to find the best way to solve a situation.

I need to choose a Service interface (and its concrete implementation) based on a variable value, in a list of several of them.

The concrete implementation extends an abstract class.

So I have

public abstract class AbstractService {

public void method1(){
//do stuff
}

public void method2(){
//do stuff
}

}

Then we have

 public interface Service1{
void method1();

    void method2();

    void method3();

    void method4();
    }

    public interface Service2 implements Service{
void method1();

    void method2();

    void method3();

    void method4();
    }

    public interface ServiceN implements Service{
void method1();

    void method2();

    void method3();

    void method4();
    }

and last, the implementations

@Service
public class Service1Implementation extends AbstractService implements Service1 {


}

@Service
public class Service2Implementation extends AbstractService implements Service2 {


}



 @Service
    public class ServiceNImplementation extends AbstractService implements ServiceN {


    }

Now, for instance, i need in a controller to decide which service i need based on a variable value.

My idea was to Autowire all the Service interfaces in the controller and then do something like this

@Controller
public class Controller{

@Autowired Service1 service1;

@Autowired Service2 service2;

//...

@Autowired ServiceN serviceN

@GetMapping("/")
public String myController(){

int variable;

switch(variable){

case 1:
service1.method()1;
break;
case 2:
service2.method1();
//....
break;
case n:
serviceN.method1();
break();

return "template";

}

}

It works... but i have several service class which extends the abstract one, it does not look like it's a well done workflow, is there a way to have it in a lighter way?

Upvotes: 0

Views: 2954

Answers (2)

davidxxx
davidxxx

Reputation: 131556

You could replace the switch statement by a Map lookup where you will provide as key, the int value that you are using in your switch and you will get as value from the map the service instance associated to.

This logical :

public String myController(){

  int variable = ;

  switch(variable){

    case 1:
     service1.method();
     break;
    case 2:
     service2.method1();
     //....
     break;
   case n:
     serviceN.method1();
     break();    
  }
  ...
}

could be replaced by :

public String myController(){
   int variable = ...;
   Service service = servicesByCode.get(variable);
   service.method1(); 
  ...
}

And as explained, you should add a Map field in the class and a method that inits the map after the beans were autowired :

private Map<Integer, Service> servicesByCode;

@PostConstruct
private void postConstruct() {
    servicesByCode = new HashMap<>();
    servicesByCode.put(1, service1);
    servicesByCode.put(2, service2);
    servicesByCode.put(3, service3);
    ...
}

Upvotes: 0

z21
z21

Reputation: 129

Use @Qualifier for this purpose. Refer this

Upvotes: 1

Related Questions