Java - 获取客户端软件包中可用的接口的所有实现

时间:2016-06-20 19:52:45

标签: java spring multithreading reflection interface

我正在开发一个任务调度程序,它使用执行程序服务并行触发任务。我希望将任务调度程序设置为通用,并且无论何时添加任何新类型的任务,都不会在调度程序代码库中更改代码或更少代码更改。

我的任务(主要是客户端包)可以是基本上只接受特定请求并执行任务的任何类型。

要做到这一点,我暴露了接口(比如说ITask),这个接口必须由任务(将在其他app / package上实现)实现,并且将有一个实现方法,例如

doTask(IRequest request);

所以用例是如果有任何客户想要使用我的调度程序框架/ API触发他们的工作,只需需要在他们的依赖项中添加我的包并休息(这些是获取列表的实现ITask的任务类>使用执行程序服务>重试失败的任务来计划它>最后提供整个任务状态)应该由我的调度API来处理。

执行此操作的最佳方法是什么。我正在考虑解决Junit如何获得其客户端的@Test方法(基于注释)谁在他的包中添加Junit依赖,同样我想要基于接口获取类。

1 个答案:

答案 0 :(得分:1)

您已使用Spring标记了此问题,但您在问题的任何位置都没有提到您正在使用Spring框架。这个答案做了一些假设:

  1. 您正在使用Spring Framework
  2. 您所需界面的实现已配置为Spring Beans
  3. 如果您可以访问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
    }
    

    这种方法显然有点危险,因为它需要你能够构建你找到的每个候选人的新实例。因此,这不是理想的解决方案。