查找实现特定接口的所有类

Ume*_*thi 34 java quartz-scheduler java-ee

我正在开发一个应用程序(Quartz调度程序),我们有一个工作类负责实际执行工作,我们需要在Quartz调度程序中创建触发器时告诉/传递作业类的名称.

我想为所有想要使用API​​的人提供一个扩展点(除了我将作为API的一部分提供的一些通用作业).我们的想法是创建一个(标记)接口,如果有人想要将它们的类声明为调度程序作业类,那么他们所要做的就是(声明)实现接口.

我不确定如何找到遵循合同的类(通过实现接口),以便我可以向想要在调度程序中安排触发器的用户显示它们.

我的要求是不在运行时加载类,而是显示实现所需接口的类的用户列表,以便用户可以选择类和类名称可以传递给调度程序.这是Quartz调度程序,它最终将负责创建类的实例.

任何人都可以建议我如何实现上述目标,还是有任何其他更好的方法来实现我想要做的事情?

编辑

我浏览了ServiceLoader的文档,似乎为了实现一个服务,我必须在META-INF文件夹中创建一个具有实现类名称的文件,这使我认为如果我的API的用户想要20个不同的实现,他必须在文件中放入20个条目,这对我来说似乎为最终用户做了很多额外的工作,因为每个工作类将被创建用于执行特定的工作,并且可以有100个工作类.

如果我的假设错了,请纠正我.

Ale*_*aev 36

你可以在这里找到答案.

我可以建议使用org.reflections

在此输入链接描述

Reflections reflections = new Reflections("com.mycompany");    
Set<Class<? extends MyInterface>> classes = reflections.getSubTypesOf(MyInterface.class);
Run Code Online (Sandbox Code Playgroud)


Sam*_*erg 34

我有类似的需求,我想确保创建的任何实现某个接口的类始终是真正可序列化的.我创建了一个JavaClassFinder,它遍历类路径中的所有目录,并找到可分配给我关心的接口的所有类.这是一段代码:

public <T> List<Class<? extends T>> findAllMatchingTypes(Class<T> toFind) {
    foundClasses = new ArrayList<Class<?>>();
    List<Class<? extends T>> returnedClasses = new ArrayList<Class<? extends T>>();
    this.toFind = toFind;
    walkClassPath();
    for (Class<?> clazz : foundClasses) {
        returnedClasses.add((Class<? extends T>) clazz);
    }
    return returnedClasses;
}
Run Code Online (Sandbox Code Playgroud)

如果有帮助,我很乐意与您分享代码.唯一的缺点是这只会处理.class文件 - 我没有添加该功能来解压缩.jars并从那里读取类文件.(但是添加它不是一个巨大的项目.)

更新:我检查了上面的源代码,发现它依赖于我们标准实用程序库中的很多辅助类.为了方便起见,我将所有需要的代码压缩,您可以从JavaClassFinder.zip下载.这将直接在Eclipse中设置,您可以获取所需代码的任何部分.

您将在项目中找到一个名为JavaClassFinderTest.java的JUnit3测试,它将向您展示JavaClassFinder类的功能和用法.运行Junit测试所需的唯一外部依赖是Junit.

该实用程序的基本用法:

    JavaClassFinder classFinder = new JavaClassFinder();
    List<Class<? extends MyTagInterface>> classes = classFinder.findAllMatchingTypes(MyTagInterface.class);
Run Code Online (Sandbox Code Playgroud)

这将为您提供一个List,其中包含类路径中可从"MyTagInterface.class"(例如)分配的任何类.希望这可以帮助.

  • @SamGoldberg你在这里设计的优秀实用工具. (3认同)