【问题标题】:Java - Using Reflections To Scan Classes From All PackagesJava - 使用反射扫描所有包中的类
【发布时间】:2021-04-19 09:13:27
【问题描述】:

我正在开发一个应用程序,它应该扫描给定类路径中的所有类和接口,并匹配一个实现类以创建 DI。

我有一个注释:

@Target(TYPE)
@Retention(RUNTIME)
public @interface RequiresBinding {

}

还有一个界面:

@RequiresBinding
public interface LowerToUpperSocketCreator {

  void createSocket(int lowerToUpperPort);

  void setIp(InetAddress ip);

  DatagramSocket getSocket();
}

问题是我无法提前知道哪些包使用了这些注解,所以我需要扫描所有有这个注解的可用类。
我试过以下代码:

Reflections reflections1 = new Reflections("", new TypeAnnotationsScanner(), new SubTypesScanner());
    Set<Class<?>> bindingProvidingClasses = reflections1.getTypesAnnotatedWith(ProvidesBinding.class);

症状是我无法找到尚未加载的类:在此示例中,与应用程序的 JAR 不同的 JAR 中的类(应用程序依赖于该 JAR)不会被扫描。
如果我将new Reflections("") 命令更改为new Reflections("com"),这意味着不是一个完全虚拟的Reflections 对象,而是一个所有包都以com 开头的对象,我确实能够扫描所有类。
有没有办法扫描类路径中的所有类,而无需任何有关相关包或可用 JAR 的信息?

【问题讨论】:

  • 可能类似于new Reflections(new ConfigurationBuilder().setUrls(ClasspathHelper.fromClasspath()).addScanners(new TypeAnnotationsScanner(), new SubTypesScanner())) - 注意这是内存不足,名称可能不同。

标签: java reflections


【解决方案1】:

您可以尝试列出所有可能的包并将它们添加到反射对象,如下所示:

Collection<URL> allPackagePrefixes = Arrays.stream(Package.getPackages()).map(p -> p.getName())
        .map(s -> s.split("\\.")[0]).distinct().map(s -> ClasspathHelper.forPackage(s)).reduce((c1, c2) -> {
            Collection<URL> c3 = new HashSet<>();
            c3.addAll(c1);
            c3.addAll(c2);
            return c3;
        }).get();
ConfigurationBuilder config = new ConfigurationBuilder().addUrls(allPackagePrefixes)
        .addScanners(Scanners.SubTypes);
Reflections reflections = new Reflections(config);

它对我有用,但我不确定它在资源方面有多昂贵。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-16
    相关资源
    最近更新 更多