我遇到了类似的问题要解决,我真正要做的是,可能会有帮助。
我有以下课程:
public enum TaskType {
VERIFY_X_TASK, COMPUTE_Y_TASK, PROCESS_Z_TASK;
}
public interface Task{
void process();
}
@Component
public class VerifyXTask implements Task{
// Similar classes for the other types of tasks
public void process() {
}
}
@Component
public class TaskFactory{
private Map<TaskType, Task> tasks;
public Task getTask(TaskType type){
return tasks.get(type); // return a singleton with all it's fields injected by the application context
}
}
class UseTool{
@Autowired
private TaskFactory taskFactory;
public void run(String taskType){
Task task = taskFactory.getTask(TaskType.valueOf(taskType));
task.process();
}
}
将TaskType和Task之间的关联注入工厂的最优雅的方法是什么?考虑到几乎有100种任务类型,并且它们可能会经常更改。
-进一步说明:我可以在TaskFactory类中做到:
tasks.put(TaskType.VERIFY_X_TASK, new VerifyTask());
tasks.put(TaskType.COMPUTE_Y_TASK, new ComputeTask());
tasks.put(TaskType.PROCESS_Z_TASK, new ProcessTask());
但是这不会在Task对象中注入任何属性。
我建议采用以下方法:
定义一个以@ImplementsTask
作为参数的自定义注释TaskType
,以便您可以这样编写实现类:
@Component
@ImplementsTask(TaskType.VERIFY_X_TASK)
public class VerifyXTask implements Task {
...
(或您可以对@Component
进行元注释,以避免必须在所有类上使用它。)>] >>
将所有已识别的Task
对象注入您的工厂:
@Autowired
private Set<Task> scannedTasks;
在工厂的@PostConstruct
方法中,迭代scannedTasks
中的每个元素,读取注释值并添加Map
条目(当然是EnumMap
的条目)。您需要确定如何处理给定TaskType
的重复实现。
[这将需要在工厂设置中进行一些反射工作,但这意味着您可以使用适当的值注释Task
实现,并且无需实施者的任何额外工作即可对其进行扫描。
我遇到了类似的问题要解决,我真正要做的是,可能会有帮助。
类似于定义任务枚举。
public enum Tasks { Task1(SubTasks.values()); Tasks(PagesEnumI[] pages) { this.pages = pages; } PagesEnumI[] pages; // define setter and getter }
定义的子任务,如
public interface PagesEnumI { String getName(); String getUrl(); } public enum SubTasks implements PagesEnumI { Home("home_url"); SubTasks(String url) { this.url = url; } private String url; @Override public String getUrl() { return url; } @Override public String getName() { return this.name(); } }
要像每个SubTasks枚举一样调用的定义服务
public interface PageI { void process(); Sites getTaskName(); PagesEnumI getSubTaskName(); } @Component public class Home implements PageI { // function per SubTask to process @Override public void process() {} // to get the information about Main Task @Override public Tasks getTaskName() { return Tasks.Task1; } // to get the information about Sub Task @Override public PagesEnumI getSubTaskName() { return Task1.Home; } }
[定义一个类似...的工厂
@Component public class PageFactory { Set<PageI> pages; // HashMap for keeping objects into private static HashMap<String, PageI> pagesFactory = new HashMap<>(); @Autowired public void setPages(Set<PageI> pages) { this.pages = pages; } // construct key by private static String constructKey(Tasks taks, PagesEnumI page) { return task.name() + "__" + page.getName(); } // PostConstruct means after construct class object this method should get run // iterating over all pages and storing into Map @PostConstruct private void postConstruct() { for (PageI pageI : pages) { pagesFactory.put(constructKey(pageI.getTaskName(), pageI.getSubTaskName()), pageI); } } // getting object from factory public PageI getPageObject(Tasks task, PagesEnumI page) { return pagesFactory.get(constructKey(task, page)); } }
到目前为止,我们已经注册了枚举(Tasks和SunTasks)及其服务(带有Tasks和SubTasks的getter,现在定义了一个工厂来调用service
process
方法。@SpringBootApplication public class Application implements CommandLineRunner { PageFactory factory; @Autowired public void setFactory(PageFactory factory) { this.factory = factory; } public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Override public void run(String... args) throws Exception { // for each task we might have different sub task Arrays.stream(Tasks.values()).forEach( task -> { // for each and subtask of a task need to perform process for (PagesEnumI page : task.getPages()) { PageI pageI = factory.getPageObject(task, page); pageI.process(); } } ); } }
这不是完全相似的问题,解决方法可能相似。因此,我认为将其放在此处可能会有所帮助。请不要输入名称,而只是试图理解概念。如果有人有更多意见,请分享。
我遇到了类似的问题要解决,我真正要做的是,可能会有帮助。