java 反射中沒有直接提供給我們方法來根據接口獲取所有實現的類,所以要自己去寫,網上資料也很多,根據通過ClassLoader獲取當前工作目錄,對目錄下的文件進行遍歷掃描。
大致思路:
1) 獲取當前線程的ClassLoader
2) 通過ClassLoader獲取當前工作目錄,對目錄下的文件進行遍歷掃描。
3) 過濾出以.class為后綴的類文件,並加載類到list中
4) 對list中所有類進行校驗,判斷是否為指定接口的實現類,並排除自身。
5) 返回所有符合條件的類。
這個思路是對的,但是考慮不全,不能拿來工程應用,另外博文中提供的源碼應該只是一個實驗代碼,有不少缺陷。
我看了就這種方法比較靠譜點,其他的好像都有問題。
自己寫ClassLoader太累,還有我們工具包reflections,這個是反射集合,需要引入jar
<dependency> <groupId>org.reflections</groupId> <artifactId>reflections</artifactId> <version>0.9.10</version> </dependency>
public static void reflectTest() { //指定掃描的包名 Reflections reflections = new Reflections("pattern.duty"); //Filter是個接口,獲取在指定包掃描的目錄所有的實現類 Set<Class<? extends Filter>> classes = reflections.getSubTypesOf(Filter.class); for (Class<? extends Filter> aClass : classes) { System.out.println(aClass.getName()); } }
就是這么簡單,主要關鍵點是指定掃描包的路徑。所以做成項目jar包時候,你要開個注冊機制填寫掃描包路徑。
以下又很多用法,構造方法里填入不同的掃描器,掃描不能的功能,如要獲取注解,就加入注解掃描器
public static void reflectionsTest() { // 掃包 Reflections reflections = new Reflections(new ConfigurationBuilder() .forPackages("com.boothsun.reflections") // 指定路徑URL .addScanners(new SubTypesScanner()) // 添加子類掃描工具 .addScanners(new FieldAnnotationsScanner()) // 添加 屬性注解掃描工具 .addScanners(new MethodAnnotationsScanner()) // 添加 方法注解掃描工具 .addScanners(new MethodParameterScanner()) // 添加方法參數掃描工具 ); // 反射出子類 Set<Class<? extends Filter>> set = reflections.getSubTypesOf(Filter.class); System.out.println("getSubTypesOf:" + set); // 反射出帶有指定注解的類 Set<Class<?>> ss = reflections.getTypesAnnotatedWith(NotMapper.class); System.out.println("getTypesAnnotatedWith:" + ss); // 獲取帶有特定注解對應的方法 Set<Method> methods = reflections.getMethodsAnnotatedWith(NotMapper.class); System.out.println("getMethodsAnnotatedWith:" + methods); // 獲取帶有特定注解對應的字段 Set<Field> fields = reflections.getFieldsAnnotatedWith(Autowired.class); System.out.println("getFieldsAnnotatedWith:" + fields); // 獲取特定參數對應的方法 Set<Method> someMethods = reflections.getMethodsMatchParams(long.class, int.class); System.out.println("getMethodsMatchParams:" + someMethods); Set<Method> voidMethods = reflections.getMethodsReturn(void.class); System.out.println("getMethodsReturn:" + voidMethods); Set<Method> pathParamMethods = reflections.getMethodsWithAnyParamAnnotated(NotMapper.class); System.out.println("getMethodsWithAnyParamAnnotated:" + pathParamMethods); }