我之前的博客(Java Scala獲取註解的類信息)介紹過經過Reflections工具經過使用特定註解的類的信息,其實本工具也能夠獲取接口,抽象類,類等的全部子類信息。使用方法以下:html
Reflections reflections = new Reflections("my.project"); Set<Class<? extends SomeType>> subTypes = reflections.getSubTypesOf(SomeType.class);
下面實例來講明如何使用的:java
定義接口:git
package test.reflection; /** * 類功能描述://TODO * * @author WangXueXing create at 19-5-4 下午10:16 * @version 1.0.0 */ public interface Base { void doSomeThing(); }
定義子類1:github
package test.reflection; /** * 類功能描述://TODO * * @author WangXueXing create at 19-5-4 下午10:18 * @version 1.0.0 */ public class SubClass1 implements Base{ @Override public void doSomeThing() { System.out.println("SubClass1"); } }
定義子類2:json
package test.reflection; /** * 類功能描述://TODO * * @author WangXueXing create at 19-5-4 下午10:18 * @version 1.0.0 */ public class SubClass2 implements Base{ @Override public void doSomeThing() { System.out.println("SubClass2"); } }
測試獲取全部Base的子類信息:app
package test.reflection; import org.reflections.Reflections; import java.util.Set; /** * 類功能描述://TODO * * @author WangXueXing create at 19-5-4 下午10:19 * @version 1.0.0 */ public class Test { public static void main(String[] args){ Reflections reflections = new Reflections("test.reflection"); Set<Class<? extends Base>> subTypes = reflections.getSubTypesOf(Base.class); subTypes.forEach(x -> System.out.println(x)); } }
結果輸出以下:maven
class test.reflection.SubClass1
class test.reflection.SubClass2
如上如何獲取全部子類信息。ide
其實Reflections還有其餘頗有用的功能,以下了解下:工具
使用默認的scanners,瀏覽url包含my.package的路徑,包括以my.package開頭的post
Reflections reflections = new Reflections("my.package");
使用ConfigurationBuilder
new Reflections(new ConfigurationBuilder() .setUrls(ClasspathHelper.forPackage("my.project.prefix")) .setScanners(new SubTypesScanner(), new TypeAnnotationsScanner().filterResultsBy(optionalFilter), ...), .filterInputsBy(new FilterBuilder().includePackage("my.project.prefix")) ...);
而後方便的使用查詢方法,這要根據具體scanners配置
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)
若是沒有配置scanner,默認使用SubTypesScanner
和TypeAnnotationsScanner
也能夠配置Classloader,用來解析某些實時類
保證可以解析到url
git上的例子:https://github.com/ronmamo/reflections/tree/master/src/test/java/org/reflections
ReflectionsUtils包含了一些方便的方法,形式相似*getAllXXX(type, withYYY)
好比
import static org.reflections.ReflectionUtils.*; Set<Method> getters = getAllMethods(someClass, withModifier(Modifier.PUBLIC), withPrefix("get"), withParametersCount(0)); //or Set<Method> listMethodsFromCollectionToBoolean = getAllMethods(List.class, withParametersAssignableTo(Collection.class), withReturnType(boolean.class)); Set<Fields> fields = getAllFields(SomeClass.class, withAnnotation(annotation), withTypeAssignableTo(type));
獲取包、class、classloader的方法
使用maven能夠很方便的集成到項目中,能夠把瀏覽的元數據存儲到xml/json文件中,下一次沒必要瀏覽,直接使用
在maven中,使用Reflections Maven plugin
插件
其餘用法
types/fields/methods/annotation
獲取包中,帶TaskOption註解的類,而後獲取註解的task()
Map<Class<? extends Task>, Class<?>> optionMap = new HashMap<>(); for (Class<?> clazz : reflections.getTypesAnnotatedWith(TaskOption.class)) { TaskOption taskOption = clazz.getAnnotation(TaskOption.class); if (taskOption == null) continue; // this shouldn't happen optionMap.put(taskOption.task(), clazz); }