SpringBoot Autowiring универсального типа не работает из-за нескольких возможных bean-компонентов - PullRequest
0 голосов
/ 20 февраля 2019

Я пытаюсь создать класс, который автоматически связывает объект типа T.

@component    
public class TaskScheduler<T extends TaskService>{
    @Autowired
    private T taskService;
}

, проблема в том, что у меня есть два компонента, которые расширяют TaskService.

@component
public class firstTaskService extends TaskService {

}

и

@component
public class secondTaskService extends TaskService {

}

поэтому при выполнении этой строки (ts создается)

@Autowired
TaskScheduler<firstTaskService> ts;

Я получаю эту ошибку:

Описание: Параметру 1 конструктора в TaskScheduler требовался один компонент, но были найдены 2

Сообщение, которое я получил, предложило следующее:

Действие: Подумайте о том, чтобы пометить один из bean-компонентов как @Primary, обновить получателя для принятия нескольких bean-компонентов или использовать @Qualifier для определения bean-компонента, который должен быть использован.аннотации @Primary и @Qualifier заставляют меня выбрать 1 из компонентов, что не то, что я хочу, потому что я хочу использовать firstTaskService и secondTaskService с тем же классом (TaskScheduler).

Как это можно сделать?

Редактировать: Уточнение: Моя цель - повторно использовать TaskScheduler clзадница с различными классами, которые расширяют класс TaskService (не использовать несколько классов, которые расширяют TaskService вместе в TaskScheduler).

1 Ответ

0 голосов
/ 20 февраля 2019

Если вы хотите автоматически связать все bean-компоненты, которые расширяются TaskService, возможно, вам следует изменить поле автонастройки на List:

@Component    
public class TaskScheduler<T extends TaskService>{
    @Autowired
    private List<T> taskService;
}

Таким образом, Spring должен добавить в List все автонастраиваемыеbean-компоненты, которые расширяются TaskService.

EDIT : поскольку вы хотите динамически выбирать тип TaskService, единственный способ, который я нашел, заключается в следующем.Во-первых, переопределите ваш TaskScheduler:

public class TaskScheduler <T extends TaskService>{

    private T taskService;

    public void setTaskService(T taskService) {
        this.taskService = taskService;
    }
}

Ваш TaskService и связанные с ним подклассы должны остаться нетронутыми.Настройте класс конфигурации следующим образом:

@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;
    }

}

И затем проверьте свой TaskScheduler следующим образом:

@Autowired
TaskScheduler<firstTaskService> ts;
...