java - 在抽象类的具体类中自动装配而不是实现接口
问题描述
我正在使用 Spring Boot,并且我有以下任务模型
public class Task {
private String name;
private TaskType type; // ManualTask, AutomatedTask
private boolean completed;
//....other fields
//getters and setters
}
控制器
@Controller
@RequestMapping("/api/task")
public class TaskController {
@Autowired
private TaskService taskService;
@GetMapping("/{taskId}/handle")
public String handle(Model model, @PathVariable("taskId") Long taskId) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
try {
Task task = taskService.handle(taskId);
model.addAttribute("task", task);
} catch (Exception e) {
return "errorpage";
}
return "successpage";
}
}
我有一个界面
public interface TaskService {
Task findById(Long taskId);
Task handleTask(Long taskId) throws ClassNotFoundException, InstantiationException, IllegalAccessException;
}
一个抽象类实现了接口:
@Service
public abstract class TaskServiceImpl implements TaskService {
@Autowired
private TaskRepository taskRepository;
private static final String PATH_OF_CLASS = "com.task.service.impl";
protected abstract Task doTypeSpecificTask(Long taskId);
@Override
public Task findById(Long taskId) {
return taskRepository.findById(taskId).get();
}
@Override
public Task handleTask(Long taskId) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Task task = findById(taskId);
TaskServiceImpl service = getHandlerService(task);
return service.doTypeSpecificTask(taskId);
}
private TaskServiceImpl getHandlerService(Task task) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
String serviceClassName = PATH_OF_CLASS.concat(".").concat(task.getTaskType().getName()).concat("Service");
Class<?> serviceClass = Class.forName(serviceClassName);
if (!TaskServiceImpl.class.isAssignableFrom(serviceClass)) {
throw new RuntimeException("Service class " + serviceClassName + " did not implements " + TaskServiceImpl.class.getName());
}
Object serviceObject = serviceClass.newInstance();
TaskServiceImpl service = (TaskServiceImpl) serviceObject;
return service;
}
}
以及扩展抽象类的具体服务
@Service
@Primary
public class ManualTaskService extends TaskServiceImpl {
@Autowired
private TaskRepository taskRepository;
@Autowired
private ManualTaskHandlerService manualTaskHandlerService;
@Override
protected Task doTypeSpecificTask(Long taskId) {
Task task = findById(taskId);
manualTaskHandlerService.handleManualTask(task);
task.setCompleted(true);
return taskRepository.save(task);
}
}
@Service
public class AutomatedTaskService extends TaskServiceImpl {
@Autowired
private TaskRepository taskRepository;
@Autowired
private AutomatedTaskHandlerService automatedTaskHandlerService;
@Override
protected Task doTypeSpecificTask(Long taskId) {
Task task = findById(taskId);
automatedTaskHandlerService.handleAutomatedTask(task);
task.setCompleted(true);
return taskRepository.save(task);
}
}
public interface TaskRepository extends JpaRepository<Task, Long> {
}
ManualTaskService
或根据AutomatedTaskService
运行时任务的类型动态选择。
现在,没有@Primary
,我收到以下错误:
Field taskService in com.test.controller.TaskController required a single bean, but 2 were found:
- manualTaskService
- automatedTaskService
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
在ManualTaskService 中@Primary
设置后,doTypeSpecificTask
在 ManualTaskService 中有效,但在 AutomatedTaskService 中由于automatedTaskHandlerService.handleAutomatedTask(task)
. 从 AutomatedTaskService 调用 taskRepository 也会失败。
我已经尝试使用@Qualifier
以及@Autowired
将抽象类中的所有内容定义为受保护但没有任何效果。我究竟做错了什么?
解决方案
每个限定符应该有不同的名称:
@Autowired
@Qualifier("manualTaskService")
private TaskServiceImpl manualTaskService;
@Autowired
@Qualifier("automatedTaskService")
private TaskServiceImpl automatedTaskService;
在服务中定义:
@Service("manualTaskService")
public class ManualTaskService extends TaskServiceImpl {
@Service("automatedTaskService")
public class AutomatedTaskService extends TaskServiceImpl {
推荐阅读
- css - 布尔玛图像下拉问题
- google-cloud-functions - 使用 Apple Android 实施登录
- java - 如何在小部件中添加垂直滚动条?
- c# - 使用VB .net在docx中用一行替换多个新行
- android - 无法将数据添加到 firebasedatabse
- php - Heroku 上的 PHP Lumen 存在 Redis 问题
- video - 如何像在 youtube 中一样在 js 视频播放器中制作拇指图片?
- google-chrome-extension - Chrome 扩展在根目录下创建 html 页面
- python - 使用 Openpyxl 在 Excel 中增加日期
- flutter - 使用 Flutter/Dart 我应该如何查询不构建小部件的数据?