Reputation: 389
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
).
Upvotes: 4
Views: 1403
Reputation: 3393
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;
Upvotes: 4