Github地址:https://github.com/ronmamo/reflections
简介
Reflections会扫描classpath,索引元数据(indexes),允许您在运行时查询它,为项目中的许多模块保存和收集信息。
使用Reflections,您可以查询:
- get all subtypes of some type 获取子类
- get all types/members annotated with some annotation 根据注解获取类型和成员变量
- get all resources matching a regular expression 根据正则匹配资源
- get all methods with specific signature including parameters, parameter annotations and return type 获取方法的获取参数、参数注解返回值
集成
Add Reflections to your project. for maven projects just add this dependency:
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.11</version>
</dependency>
A typical use of Reflections would be:
Reflections reflections = new Reflections("my.project");
Set<Class<? extends SomeType>> subTypes = reflections.getSubTypesOf(SomeType.class);
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(SomeAnnotation.class);
注意,可能与其他库有冲突,如google-collections
。类似见issue: https://github.com/ronmamo/reflections/issues/194
使用
1). 使用Reflections首先通过urls
和scaner
进行初始化
- 方式1: 直接接包名,此时使用默认的
scaner
- 方式2: 使用
ConfigurationBuilder
构建
Reflections reflections = new Reflections("my.package");
new Reflections(new ConfigurationBuilder()
.setUrls(ClasspathHelper.forPackage("my.project.prefix"))
.setScanners(new SubTypesScanner(),
new TypeAnnotationsScanner().filterResultsBy(optionalFilter), ...),
.filterInputsBy(new FilterBuilder().includePackage("my.project.prefix"))
...);
2). 直接调用查询方法(取决于配置的scanner配置)
//SubTypesScanner
Set<Class<? extends Module>> modules =
reflections.getSubTypesOf(com.google.inject.Module.class);
//TypeAnnotationsScanner
Set<Class<?>> singletons =
reflections.getTypesAnnotatedWith(javax.inject.Singleton.class);
//ResourcesScanner
Set<String> properties =
reflections.getResources(Pattern.compile(".*\\.properties"));
//MethodAnnotationsScanner
Set<Method> resources =
reflections.getMethodsAnnotatedWith(javax.ws.rs.Path.class);
Set<Constructor> injectables =
reflections.getConstructorsAnnotatedWith(javax.inject.Inject.class);
//FieldAnnotationsScanner
Set<Field> ids =
reflections.getFieldsAnnotatedWith(javax.persistence.Id.class);
//MethodParameterScanner
Set<Method> someMethods =
reflections.getMethodsMatchParams(long.class, int.class);
Set<Method> voidMethods =
reflections.getMethodsReturn(void.class);
Set<Method> pathParamMethods =
reflections.getMethodsWithAnyParamAnnotated(PathParam.class);
//MethodParameterNamesScanner
List<String> parameterNames =
reflections.getMethodParamNames(Method.class)
//MemberUsageScanner
Set<Member> usages =
reflections.getMethodUsages(Method.class)
- 如果
scanners
没有配置,默认将会使用SubTypesScanner
和TypeAnnotationsScanner
- 还可以配置
Classloader
,它将根据名称中解析运行时类。
- Reflection默认情况下会扩展超类。这解决了传输URL不被扫描的一些问题。
Checkout the javadoc for more info.
Also, browse the tests directory to see some more examples.
ReflectionUtils
ReflectionsUtils包含一些方便的Java反射辅助方法,用于获取匹配types/constructors/methods/fields/annotations,通常采用谓词,如* getAllXXX(type,withYYY)的格式。
举例:
import static org.reflections.ReflectionUtils.*;
Set<Method> getters = getAllMethods(someClass,
withModifier(Modifier.PUBLIC), withPrefix("get"), withParametersCount(0));
Set<Method> listMethodsFromCollectionToBoolean =
getAllMethods(List.class,
withParametersAssignableTo(Collection.class), withReturnType(boolean.class));
Set<Field> fields = getAllFields(SomeClass.class, withAnnotation(annotation), withTypeAssignableTo(type));
See more in the ReflectionUtils javadoc
例子
Reflections reflections = new Reflections("cc.tyrad.smartservice");
Set<Class<? extends com.baomidou.mybatisplus.extension.activerecord.Model>> subTypes = reflections.getSubTypesOf(com.baomidou.mybatisplus.extension.activerecord.Model.class);
for (Class<? extends com.baomidou.mybatisplus.extension.activerecord.Model> class1 : subTypes) {
log.info("获取Model的子类=:{}", class1.toString());
}
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(RestController.class);
for (Class<?> class1 : annotated) {
log.info("获取包含RestController注解的类=:{}", class1.toString());
}