使用反射库查询Java类路径中具有任意属性的类
在过去,我使用库来查询类路径中具有特定注释或从特定类继承的类。 这对于反射非常容易,因为库已经提供了回答此类特定查询的方法 例如,下面的代码说明了如何查询继承自使用反射库查询Java类路径中具有任意属性的类,java,reflections,Java,Reflections,在过去,我使用库来查询类路径中具有特定注释或从特定类继承的类。 这对于反射非常容易,因为库已经提供了回答此类特定查询的方法 例如,下面的代码说明了如何查询继承自SomeType的类和用SomeAnnotation注释的类,查找位于包my.package.prefix中的类(示例取自Reflection.java类的文档): 所以我的问题是,一旦我有了这个strategy对象,我如何指示Reflections库过滤类,只保留那些根据程序员定义的strategy类匹配的类 更新: 显然,过滤部分不是
SomeType
的类和用SomeAnnotation
注释的类,查找位于包my.package.prefix
中的类(示例取自Reflection.java类的文档):
所以我的问题是,一旦我有了这个strategy对象,我如何指示Reflections库过滤类,只保留那些根据程序员定义的strategy类匹配的类
更新:
显然,过滤部分不是最困难的任务(感谢@MvG的回答),而是实际收集所有要过滤的类(通常是程序员定义的一组基本包中的类)。
因此,我们的想法是查询所有类,然后使用以下方法过滤它们:
ReflectionUtils.getAll(所有类,谓词)
然后,为了获得要过滤的类的初始集合,我尝试在程序员选择的特定包中查询对象
的所有子类型
下面是我为此使用的代码:
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);
ConfigurationBuilder config=new ConfigurationBuilder();
FilterBuilder fb=新的FilterBuilder();
包括(FilterBuilder.prefix(“my.package.prefix”);
配置filternputsby(fb);
config.setURL(ClasspathHelper.forPackage(“my.package.prefix”);
配置设置扫描程序(新的子扫描程序(错误))//SubsubsScanner构造函数中的第一个参数指示是否应忽略对象类
反射=新反射(配置);
设置使用com.google.common.base.Predicate
来表达您的策略,或者将您自己的策略对象包装到此类谓词中。然后你就可以写了
ReflectionUtils.getAll(allClasses, predicate);
看来,实际计算这个所有类iterable将是一项要求更高的任务。乍一看,我看不到简单的API。您可能需要直接访问底层存储,并自己将类名转换为class
对象。这意味着加载所有类,这可能非常耗时,在某些情况下甚至可能失败
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);
ReflectionUtils.getAll(allClasses, predicate);