? ?之前在看spring注解的时候,有看到再配置文件里面定义component scan package就能自动扫描对应包下面的class,
然后根据注解生成相应的bean。自己对这个功能很好奇,就搜了下,找到了实现的关键代码,记录下。后续再对这段代码深入学习。
?
?
Java代码??
- ?
- ?
- ?
- ?
- ?
- ??
- ????public?static?Set<Class<?>>?getClasses(String?pack)?{??
- ??
- ??????????
- ????????Set<Class<?>>?classes?=?new?LinkedHashSet<Class<?>>();??
- ??????????
- ????????boolean?recursive?=?true;??
- ??????????
- ????????String?packageName?=?pack;??
- ????????String?packageDirName?=?packageName.replace('.',?'/');??
- ??????????
- ????????Enumeration<URL>?dirs;??
- ????????try?{??
- ????????????dirs?=?Thread.currentThread().getContextClassLoader().getResources(??
- ????????????????????packageDirName);??
- ??????????????
- ????????????while?(dirs.hasMoreElements())?{??
- ??????????????????
- ????????????????URL?url?=?dirs.nextElement();??
- ??????????????????
- ????????????????String?protocol?=?url.getProtocol();??
- ??????????????????
- ????????????????if?("file".equals(protocol))?{??
- ????????????????????System.err.println("file类型的扫描");??
- ??????????????????????
- ????????????????????String?filePath?=?URLDecoder.decode(url.getFile(),?"UTF-8");??
- ??????????????????????
- ????????????????????findAndAddClassesInPackageByFile(packageName,?filePath,??
- ????????????????????????????recursive,?classes);??
- ????????????????}?else?if?("jar".equals(protocol))?{??
- ??????????????????????
- ??????????????????????
- ????????????????????System.err.println("jar类型的扫描");??
- ????????????????????JarFile?jar;??
- ????????????????????try?{??
- ??????????????????????????
- ????????????????????????jar?=?((JarURLConnection)?url.openConnection())??
- ????????????????????????????????.getJarFile();??
- ??????????????????????????
- ????????????????????????Enumeration<JarEntry>?entries?=?jar.entries();??
- ??????????????????????????
- ????????????????????????while?(entries.hasMoreElements())?{??
- ??????????????????????????????
- ????????????????????????????JarEntry?entry?=?entries.nextElement();??
- ????????????????????????????String?name?=?entry.getName();??
- ??????????????????????????????
- ????????????????????????????if?(name.charAt(0)?==?'/')?{??
- ??????????????????????????????????
- ????????????????????????????????name?=?name.substring(1);??
- ????????????????????????????}??
- ??????????????????????????????
- ????????????????????????????if?(name.startsWith(packageDirName))?{??
- ????????????????????????????????int?idx?=?name.lastIndexOf('/');??
- ??????????????????????????????????
- ????????????????????????????????if?(idx?!=?-1)?{??
- ??????????????????????????????????????
- ????????????????????????????????????packageName?=?name.substring(0,?idx)??
- ????????????????????????????????????????????.replace('/',?'.');??
- ????????????????????????????????}??
- ??????????????????????????????????
- ????????????????????????????????if?((idx?!=?-1)?||?recursive)?{??
- ??????????????????????????????????????
- ????????????????????????????????????if?(name.endsWith(".class")??
- ????????????????????????????????????????????&&?!entry.isDirectory())?{??
- ??????????????????????????????????????????
- ????????????????????????????????????????String?className?=?name.substring(??
- ????????????????????????????????????????????????packageName.length()?+?1,?name??
- ????????????????????????????????????????????????????????.length()?-?6);??
- ????????????????????????????????????????try?{??
- ??????????????????????????????????????????????
- ????????????????????????????????????????????classes.add(Class??
- ????????????????????????????????????????????????????.forName(packageName?+?'.'??
- ????????????????????????????????????????????????????????????+?className));??
- ????????????????????????????????????????}?catch?(ClassNotFoundException?e)?{??
- ??????????????????????????????????????????????
- ??????????????????????????????????????????????
- ????????????????????????????????????????????e.printStackTrace();??
- ????????????????????????????????????????}??
- ????????????????????????????????????}??
- ????????????????????????????????}??
- ????????????????????????????}??
- ????????????????????????}??
- ????????????????????}?catch?(IOException?e)?{??
- ??????????????????????????
- ????????????????????????e.printStackTrace();??
- ????????????????????}??
- ????????????????}??
- ????????????}??
- ????????}?catch?(IOException?e)?{??
- ????????????e.printStackTrace();??
- ????????}??
- ??
- ????????return?classes;??
- ????}??
?
?
Java代码??
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ??
- ????public?static?void?findAndAddClassesInPackageByFile(String?packageName,??
- ????????????String?packagePath,?final?boolean?recursive,?Set<Class<?>>?classes)?{??
- ??????????
- ????????File?dir?=?new?File(packagePath);??
- ??????????
- ????????if?(!dir.exists()?||?!dir.isDirectory())?{??
- ??????????????
- ????????????return;??
- ????????}??
- ??????????
- ????????File[]?dirfiles?=?dir.listFiles(new?FileFilter()?{??
- ??????????????
- ????????????public?boolean?accept(File?file)?{??
- ????????????????return?(recursive?&&?file.isDirectory())??
- ????????????????????????||?(file.getName().endsWith(".class"));??
- ????????????}??
- ????????});??
- ??????????
- ????????for?(File?file?:?dirfiles)?{??
- ??????????????
- ????????????if?(file.isDirectory())?{??
- ????????????????findAndAddClassesInPackageByFile(packageName?+?"."??
- ????????????????????????+?file.getName(),?file.getAbsolutePath(),?recursive,??
- ????????????????????????classes);??
- ????????????}?else?{??
- ??????????????????
- ????????????????String?className?=?file.getName().substring(0,??
- ????????????????????????file.getName().length()?-?6);??
- ????????????????try?{??
- ??????????????????????
- ??????????????????????
- ???????????????????????????????????????????
- ????????????????????????????????????????classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName?+?'.'?+?className));????
- ????????????????????????????????}?catch?(ClassNotFoundException?e)?{??
- ??????????????????????
- ????????????????????e.printStackTrace();??
- ????????????????}??
- ????????????}??
- ????????}??
- ????}??
?
?
??????? 自己直接拿过来用了,可以扫描package对应的子package,不过是对当前classLoad下的所有jar进行扫描的。