背景
最近在設(shè)計和開發(fā)部門的基礎(chǔ)架構(gòu),需要利用反射技術(shù)找到classpath目錄下所有包含指定注解的類,然后根據(jù)注解配置完成指定的功能赊颠。
最初是想自己寫代碼來實現(xiàn)這些功能,邊查資料邊寫劈彪,整了大半天竣蹦,寫出來的效果自己都不太滿意。一方面是代碼多沧奴,不好維護痘括;另一方面是性能不太好。不過滔吠,在查資料的過程中纲菌,我發(fā)現(xiàn)了一個非常好用的反射框架:reflections。
reflections簡單好用疮绷,性能也不錯驰后,很快就完成了我想要的功能,就是這么優(yōu)秀矗愧!
簡介
Reflections通過掃描classpath灶芝,索引元數(shù)據(jù),并且允許在運行時查詢這些元數(shù)據(jù)唉韭。
使用Reflections可以很輕松的獲取以下元數(shù)據(jù)信息:
- 獲取某個類型的全部子類
- 只要類型夜涕、構(gòu)造器、方法属愤,字段上帶有特定注解女器,便能獲取帶有這個注解的全部信息(類型、構(gòu)造器住诸、方法驾胆,字段)
- 獲取所有能匹配某個正則表達式的資源
- 獲取所有帶有特定簽名的方法,包括參數(shù)贱呐,參數(shù)注解丧诺,返回類型
- 獲取所有方法的名字
- 獲取代碼里所有字段、方法名奄薇、構(gòu)造器的使用
Maven依賴
在pom.xml中添加reflections的依賴:
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.11</version>
</dependency>
// 實例化Reflections驳阎,并指定要掃描的包名
Reflections reflections = new Reflections("my.project");
// 獲取某個類的所有子類
Set<Class<? extends SomeType>> subTypes = reflections.getSubTypesOf(SomeType.class);
// 獲取包含某個注解的所有類
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(SomeAnnotation.class);
使用
//scan urls that contain 'my.package', include inputs starting with 'my.package', use the default scanners
Reflections reflections = new Reflections("my.package");
//or using 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"))
...);
掃描子類
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);
掃描方法參數(shù)
//MethodParameterScanner
Set<Method> someMethods =
reflections.getMethodsMatchParams(long.class, int.class);
Set<Method> voidMethods =
reflections.getMethodsReturn(void.class);
Set<Method> pathParamMethods =
reflections.getMethodsWithAnyParamAnnotated(PathParam.class);
掃描方法參數(shù)名
//MethodParameterNamesScanner
List<String> parameterNames =
reflections.getMethodParamNames(Method.class)
掃描方法調(diào)用情況
//MemberUsageScanner
Set<Member> usages =
reflections.getMethodUsages(Method.class)