Reputation: 35
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.
Upvotes: 0
Views: 546
Reputation: 7521
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;
Upvotes: 2
Reputation: 1732
You could merge the following solutions:
Creating an instance from String in Java
private @Autowired AutowireCapableBeanFactory beanFactory;
public void doStuff() {
Class c= Class.forName(className);
MyBean obj = c.newInstance();
beanFactory.autowireBean(obj);
// obj will now have its dependencies autowired.
}
Upvotes: 0
Reputation: 9374
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.
Upvotes: 1