扫描单个子类的Java类路径?

时间:2013-09-20 15:39:17

标签: java reflection classpath classloader war

我有一个相当独特的情况,我知道我的Java Web应用程序将始终打包为AbstractWidget的1-only-1具体子类:

public abstract class AbstractWidget {
    // ...
}

public class SimpleWidget extends AbstractWidget {
    // ...
}

public class ComplexWidget extends AbstractWidget {
    // ...
}

public class CrazyComplexWidget extends AbstractWidget {
    // ...
}

// ...etc.

同样,我在运行时知道我的WAR/WEB-INF/classes目录将始终包含1个且仅1 AbstractWidget个impl(不多也不少),不管是{{1} },ComplexWidget.class

我正在尝试构建代码(当WAR从其SimpleWidget.class impl内部启动时实际运行),该代码将能够扫描运行时类路径并获取实例(使用公共否-arg构造函数ServletContextListener

因此,如果我的WAR有:

AbstractWidget

然后,从myWar/ WEB-INF/ lib/ classes/ com/ myorg/ App (implements ServletContextListener) ... lots of other classes and packages some/ arbitrary/ package/ SimpleWidget 内部我需要在类路径上找到App#contextInitialized(ServletContextEvent)的代码并给我一个实例:

SimpleWidget.class

我知道你可以使用像public class App implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent event) { // Scan classpath for the lone AbstractWidget impl somehow. ??? // Use public, no-arg ctor to instantiate the impl. AbstractWidget widget = ??? // Now do stuff with widget... } } 这样的反射方法,但不确定这是否是正确的方法,即使它是,如何将它用于我的给定用例。有任何想法吗?提前谢谢!

2 个答案:

答案 0 :(得分:0)

您可能想要查看the reflections api.它具有用于查找给定类的子类的实用程序。你可以用它做这样的事情:

Reflections reflections = new Reflections();
Set<Class<? extends AbstractWidget>> subclasses;
subclasses = reflections.getSubTypesOf(AbstractWidget.class);

这将为您提供Set,其中包含类路径上AbstractWidget类的所有子类。 http://code.google.com/p/reflections/

答案 1 :(得分:0)

我知道这是一个非常老的问题,但是ClassGraph库可以帮助您轻松地在类路径中获取扩展给定类的所有类,基本上是给定类的所有子类。

等级依赖性

compile group: 'io.github.classgraph', name: 'classgraph', version: '4.8.46'

通过这种方式可以轻松地扫描类路径

ScanResult scanResult = new ClassGraph()
    .whitelistPackages("com.myorg") //whatever package you want to scan
    .verbose()
    .enableAllInfo() 
    .scan();

System.out.println("Classes which extending '" + AbstractWidget.class.getSimpleName() + "' class");
ClassInfoList classInfoList = scanResult.getSubclasses(AbstractWidget.class.getName());
for (ClassInfo classInfo : classInfoList) {
    System.out.println("\t" + classInfo.getName());
}

假设您在类路径中有SimpleWidget类,则输出

Classes which extending 'AbstractWidget' class
    com.myorg.some.arbitrary.package.SimpleWidget

我希望它会有所帮助。 ClassGraph是一个功能强大的库,可以满足此简单需求。 https://readtorakesh.com/java-classpath-scanning-using-classgraph/

中对它的解释非常好