我正在开发一个任务调度程序,它使用执行程序服务并行触发任务。我希望将任务调度程序设置为通用,并且无论何时添加任何新类型的任务,都不会在调度程序代码库中更改代码或更少代码更改。
我的任务(主要是客户端包)可以是基本上只接受特定请求并执行任务的任何类型。
要做到这一点,我暴露了接口(比如说ITask),这个接口必须由任务(将在其他app / package上实现)实现,并且将有一个实现方法,例如
doTask(IRequest request);
所以用例是如果有任何客户想要使用我的调度程序框架/ API触发他们的工作,只需需要在他们的依赖项中添加我的包并休息(这些是获取列表的实现ITask的任务类>使用执行程序服务>重试失败的任务来计划它>最后提供整个任务状态)应该由我的调度API来处理。
执行此操作的最佳方法是什么。我正在考虑解决Junit如何获得其客户端的@Test方法(基于注释)谁在他的包中添加Junit依赖,同样我想要基于接口获取类。
答案 0 :(得分:1)
您已使用Spring标记了此问题,但您在问题的任何位置都没有提到您正在使用Spring框架。这个答案做了一些假设:
如果您可以访问ApplicationContext(请参阅ApplicationContextAware接口),您可以使用它来查找某种类型的Spring bean。它看起来像这样:
Map<String, ITask> beans = appContext.getBeansOfType(ITask.class);
此方法返回一个映射,其中键是bean标识符,值是bean本身的实例。从那里,您可以遍历这些值并将它们添加到您的作业调度程序中。
<强>替代地强>
如果您不希望必须将每个ITask实现配置为Spring bean,那么您可以使用Spring ClassPathScanningCandidateComponentProvider
(我知道一口)。
这是一个漂亮的工具,允许您扫描基础包以找到bean&#34;候选人&#34;。但是,在您的情况下,您可以使用它来查找ITask候选人。您的库的客户端可以配置您将用于扫描的基本扫描包:
private String configuredListOfBasePackages;
public void someMethod () {
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AssignableTypeFilter(ITask.class));
Set<BeanDefinition> iTaskCandidates = scanner.findCandidateComponents(configuredListOfBasePackages);
// do stuff with the bean definitions
}
这种方法显然有点危险,因为它需要你能够构建你找到的每个候选人的新实例。因此,这不是理想的解决方案。