0

I have an interface as following:

public interface Solver {
    void execute(final String definition);
}

I have several solver implementations. For example:

@Qualifier("naive")
@Service
public class NaiveSolver implements Solver {
    @Override
    public void execute(final String definition) {
    }
}

@Qualifier("optimal")
@Service
public class OptimalSolver implements Solver {
    @Override
    public void execute(final String definition) {
    }
}

Now, in my database I have the data for these solvers as following:

type:       textual - examples: simple, naive
definition: textual

When fetching this data, I need to map the type column to the actual service instance, so it can solve the provided definition.

So, my question boils down to this: how can I, given a type string, get the instance of the corresponding Solver service instance of which the qualifier is equal to that type? I believe that @Autowired cannot be used here, as I need to find beans dynamically at runtime.

Hazzo
  • 15
  • 4

3 Answers3

2

Since Spring 4 you can autowire multiple implemetations into a Map where bean qualifier is a key, and the bean itself is a value

@Autowired
private Map<String, Solver> solvers;

void doStuff() {
    String type = ... // obtain type
    Solver solver = solvers.get(type);
    solver.execute(...)
}

Update

Correct way of naming a bean is not

@Qualifier("naive")
@Service

but

@Service("naive")

@Qualifier is used along with @Autowired to ensure the correct bean is injected

@Autowired
@Qualifier("naive")
private Solver naiveSolver;
Nikolai Shevchenko
  • 7,083
  • 8
  • 33
  • 42
1

You can create configuration which will just hold mapping to your solvers:

@Autowired
@Qualifier("optimal")
private Solver naiveSolver;

@Bean
public Map<String, Solver> mapSolver() {
   Map<String, Solver> map = new HashMap<>();
   map.put("naive", naiveSolver);
   return map;
}

Or even going further you can follow factory pattern which will provide you different instances of solvers.

Another way you can dynamically get those beans from application context.

Igor Konoplyanko
  • 9,176
  • 6
  • 57
  • 100
  • Thank you. I believe the application context already holds all beans, with their possible qualifiers. So while I could manage my own map, I believe that's re-inventing what the application context already is doing. So in other words: I am interested in how to find the qualified service from the application context. Could you please show me how this can be done? – Hazzo Apr 02 '20 at 11:12
0

You could merge the following solutions:

Michel Foucault
  • 1,724
  • 3
  • 25
  • 48