【发布时间】:2012-08-08 21:40:35
【问题描述】:
我过去曾使用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);
但是,在我当前的问题中,我需要做的是查询具有 arbitrary 属性集的类(例如,特定类名 + 现有注释 + 任何东西的组合)。我事先并不知道这些属性,因为它们应该由程序员使用我正在开发的库来定义。
我设想解决方案的一部分类似于要求程序员定义一个带有布尔方法的 Strategy 类,以回答该类是否应该在答案集中。
例如,程序员应该实现一个类似的接口:
public interface MyStrategy {
public boolean match(Class clazz);
}
所以我的问题是,一旦我有了这个策略对象,我如何指示反射库过滤类,只保留那些根据程序员定义的策略类匹配的类?
更新:
显然过滤部分不是最困难的任务(感谢@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);
这是最好(更有效)的解决方案吗?
有人有其他想法吗?提前致谢!
【问题讨论】:
标签: java reflections