当前位置: 首页 > 知识库问答 >
问题:

使用反射库查询Java类路径中具有任意属性的类

单于轶
2023-03-14

我过去曾使用Reflections库查询类路径中具有特定注释或从特定类继承的类。这对反射非常容易,因为库已经提供了回答此类特定查询的方法。

例如,下面的代码说明了如何查询从SomeType继承的类和用SomeAnnotation注释的类,查找位于包My.package.Prefix中的类(示例取自Reflection.java类的文档):

Reflections reflections = new Reflections("my.package.prefix");
Set<Class<? extends SomeType>> subTypes = reflections.getSubTypesOf(SomeType.class);
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(SomeAnnotation.class);

然而,在我当前的问题中,我需要做的是查询具有任意属性集的类(例如,特定类名+现有注释+其他)。我事先不知道这些属性,因为它们应该由程序员使用我正在开发的库定义。

我设想,解决方案的一部分将是要求程序员用一个布尔方法定义一个策略类,回答这个类是否应该在答案集中。

例如,程序员应该实现一个类似于以下内容的接口:

public interface MyStrategy {
    public boolean match(Class clazz);
}

所以我的问题是,一旦我有了这个strategy对象,我如何指示Reflections库过滤类,只保留那些根据程序员定义的strategy类匹配的?

更新:

很明显,过滤部分并不是最困难的任务(谢谢回答@mvg),而是实际收集所有要过滤的类(通常是程序员定义的一组基本包中的类)。因此,我们的想法是查询所有的类,然后用ReflectionUtils.getAll(allClasses,predicate)方法过滤它们。

然后,为了获得要过滤的初始类集,我尝试在程序员选择的特定包中查询object的所有子类型。

下面是我为此使用的代码:

ConfigurationBuilder config = new ConfigurationBuilder();
FilterBuilder fb = new FilterBuilder();
fb.include(FilterBuilder.prefix("my.package.prefix"));
config.filterInputsBy(fb);
config.setUrls(ClasspathHelper.forPackage("my.package.prefix"));
config.setScanners(new SubTypesScanner(false)); //the first argument at the constructor of SubTypesScanner indicates if the Object class should be ignored
Reflections reflections = new Reflections(config);
Set<Class<? extends Object>> unfilteredClasses = reflections.getSubTypesOf(Object.class);

这是最好的(更有效率的)解决方案吗?

有人有别的主意吗?。提前道谢!

共有1个答案

郎河
2023-03-14

使用com.google.common.base.predicate来表达策略,或者将自己的策略对象包装到这样的谓词中。然后你就可以写了

ReflectionUtils.getAll(allClasses, predicate);

看来,实际计算allclasses可迭代是一项要求更高的任务。乍一看,我没有看到任何简单的API。您可能必须直接访问底层存储,并自己将类名转换为class对象。这意味着要加载所有的类,这可能非常耗时,甚至在某些情况下可能会失败。

 类似资料:
  • 使用docx4j,我能够解析来自CTRect和CTOval对象的椭圆和矩形。但是当我使用自定义形状时,docx4j给出了CTShape或CTShapeType中的对象。我已经阅读了VML规范链接。 路径值有时具有以下值 null

  • 我有一个Java 8应用程序,我正在将其转换为Java 11,当然,我第一次使用这个模块系统。 我设置了应用程序Maven程序集配置,以便将所有JAR文件放在bin发行版的 /lib目录中。然后,maven-jar-plugin使用所有JAR文件名设置MANIFEST Class-Path值。应用程序使用简单的运行 转到Java11,如果我继续以这种方式构建bin分发,我很想知道运行时如何解释MA

  • 问题内容: 任何人都可以解释一下Spring中path属性如何将对象从html形式绑定到Java类。我是Spring Web Framework的新手,请帮忙。 问题答案: 长话短说,使用Java bean约定将path属性绑定到Java属性中。例如以下形式: 以及以下控制器处理程序方法: 如果使用以下属性定义了Student类,则将自动绑定: 规范文档的第8.3节提供了有关JavaBeans对流

  • 例如,如何使用spring-kafka(不带sboot)进行SSL配置,使用相对/类路径指定信任库的位置? 仅当提供了绝对路径时,它才起作用。 令人惊讶的是,当使用Spring引导运行时,它可以使用相对路径(在jar内)。。

  • 在“Kotlin in Action”中,它说“如果一个成员属性引用了Person类的年龄属性,memberProperty.get(person)是一种动态获取person.age值的方法”,代码为(10.2.1 Kotlin Reflection API): 我不明白为什么这个例子提到“动态”获取属性的值。当我运行以下代码时,它才起作用: 是否有其他成员属性反射的案例或示例?

  • 我的域类中有一个map属性,我正在尝试在存储库中创建一个查询,或者使用默认的“findByBlah”语法从数据库中提取属性。目前不起作用。我可以很容易地用SQL编写查询,但我不知道JPQL需要什么。如何使用JPQL或接口“findBy”语法从数据库中提取这些数据?无论我当前使用哪种存储库方法,当它从数据库中提取“收集器”时,属性(映射或复杂对象列表)始终为空。 域对象: 存储库: 这是在H2控制台