I'm trying to create a class that Autowire an object of type T.
@component
public class TaskScheduler<T extends TaskService>{
@Autowired
private T taskService;
}
the problem is that I have two components that extend TaskService
.
@component
public class firstTaskService extends TaskService {
}
and
@component
public class secondTaskService extends TaskService {
}
so when this line is executed (ts
is being created)
@Autowired
TaskScheduler<firstTaskService> ts;
I get this error :
Description: Parameter 1 of constructor in TaskScheduler required a single bean, but 2 were found
the message I got suggested this :
Action: Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed.
But from what I understood, the @Primary
and @Qualifier
annotations make me choose 1 of the components, which not what I want because I want to use firstTaskService
and secondTaskService
with that same class (TaskScheduler
).
How could this be done?
Edit: Clarification: My objective is to reuse the TaskScheduler
class with different classes that extend the TaskService
class (not to use multiple classes that extend TaskService
together in TaskScheduler
).
If you want to autowire all beans that extends TaskService
maybe you should change the autowired field to a List
:
@Component
public class TaskScheduler<T extends TaskService>{
@Autowired
private List<T> taskService;
}
In this way Spring should put in the List
all autowireable beans that extends TaskService
.
EDIT: since you want to dinamically select the type of TaskService
the only way I've found is the following. First, redefine your TaskScheduler
:
public class TaskScheduler <T extends TaskService>{
private T taskService;
public void setTaskService(T taskService) {
this.taskService = taskService;
}
}
Your TaskService
and related subclasses should remain untouched. Set up a configuration class as it follows:
@Configuration
public class TaskConf {
@Autowired
private FirstTaskService firstTaskService;
@Autowired
private SecondTaskService secondTaskService;
@Bean
public TaskScheduler<FirstTaskService> firstTaskServiceTaskScheduler(){
TaskScheduler<FirstTaskService> t = new TaskScheduler<>();
t.setTaskService(firstTaskService);
return t;
}
@Bean
public TaskScheduler<SecondTaskService> secondTaskServiceTaskScheduler(){
TaskScheduler<SecondTaskService> t = new TaskScheduler<>();
t.setTaskService(secondTaskService);
return t;
}
}
And then test your TaskScheduler
in this way:
@Autowired
TaskScheduler<firstTaskService> ts;