做wps的网站赚钱,网站建设中网站图片如何修改,深圳平台型网站建设公司,上海优化公司排行榜背景用过spring框架之后#xff0c;有个指定扫描包路径#xff0c;然后自动实例化一些bean#xff0c;这个过程还是比较有意思的#xff0c;抽象一下#xff0c;即下面三个点如何扫描包路径下所有的class文件如何扫描jar包中对应包路径下所有的class文件如何加载class文件…背景用过spring框架之后有个指定扫描包路径然后自动实例化一些bean这个过程还是比较有意思的抽象一下即下面三个点如何扫描包路径下所有的class文件如何扫描jar包中对应包路径下所有的class文件如何加载class文件实现目标我们的目标是给定一个包路径然后加载这个包路径下的所有class考虑两种场景包路径为依赖第三方jar包中的包路径为自己的业务代码中的 --》 常见的一种是业务代码会编译成class文件即扫描文件实现针对上面两种场景分开说明1. 扫描文件实现流程比较清晰根据包名获取绝对地址直接进入包对应的目录扫描目录下所有文件加载所有的class文件如果是目录迭代遍历目录下的class文件加载class文件获取包对应的绝对地址这里先不说下面直接给出进入目录加载所有class文件的代码/*** 扫描包路径下的所有class文件** param pkgName 包名* param pkgPath 包对应的绝对地址* param classes 保存包路径下class的集合*/private static void findClassesByFile(String pkgName, String pkgPath, Set classes) {File dir new File(pkgPath);if (!dir.exists() || !dir.isDirectory()) {return;}// 过滤获取目录or class文件File[] dirfiles dir.listFiles(pathname - pathname.isDirectory() || pathname.getName().endsWith(class));if (dirfiles null || dirfiles.length 0) {return;}String className;Class clz;for (File f : dirfiles) {if (f.isDirectory()) {findClassesByFile(pkgName . f.getName(),pkgPath / f.getName(),classes);continue;}// 获取类名干掉 .class 后缀className f.getName();className className.substring(0, className.length() - 6);// 加载类clz loadClass(pkgName . className);if (clz ! null) {classes.add(clz);}}}2. 扫描jar流程和上面一样实现上稍稍有些区别由之前的扫描文件变成遍历JarFile/*** 扫描包路径下的所有class文件** param pkgName 包名* param jar jar文件* param classes 保存包路径下class的集合*/private static void findClassesByJar(String pkgName, JarFile jar, Set classes) {String pkgDir pkgName.replace(., /);Enumeration entry jar.entries();JarEntry jarEntry;String name, className;Class claze;while (entry.hasMoreElements()) {jarEntry entry.nextElement();name jarEntry.getName();if (name.charAt(0) /) {name name.substring(1);}if (jarEntry.isDirectory() || !name.startsWith(pkgDir) || !name.endsWith(.class)) {// 非指定包路径 非class文件continue;}// 去掉后面的.class, 将路径转为package格式className name.substring(0, name.length() - 6);claze loadClass(className.replace(/, .));if (claze ! null) {classes.add(claze);}}}3. 扫描包上面是具体的扫class文件的过程那么如何根据包获取对应的jarFile or 包对应的绝对地址呢主要利用的是 XXX.class.getClassLoader().getResources(package), 具体如下/*** 扫描包路径下所有的class文件** param pkg* return*/public static Set getClzFromPkg(String pkg) {Set classes new LinkedHashSet();String pkgDirName pkg.replace(., /);try {Enumeration urls PkgUtil.class.getClassLoader().getResources(pkgDirName);while (urls.hasMoreElements()) {URL url urls.nextElement();String protocol url.getProtocol();if (file.equals(protocol)) {// 如果是以文件的形式保存在服务器上String filePath URLDecoder.decode(url.getFile(), UTF-8);// 获取包的物理路径findClassesByFile(pkg, filePath, classes);} else if (jar.equals(protocol)) {// 如果是jar包文件JarFile jar ((JarURLConnection) url.openConnection()).getJarFile();findClassesByJar(pkg, jar, classes);}}} catch (IOException e) {e.printStackTrace();}return classes;}4. 类加载这个还是比较简单的一搜一大把直接贴出private static Class loadClass(String fullClzName) {try {return Thread.currentThread().getContextClassLoader().loadClass(fullClzName);} catch (ClassNotFoundException e) {log.error(load class error! clz: {}, e:{}, fullClzName, e);}return null;}测试要愉快的测试这一功能你可以选择一个jar包如 org.slf4j, 然后自己创建几个测试类包名也是已 org.slf4j开头然后调用上面的方法Class set PkgUtil.getClzFromPkg(org.slf4j);因为这个工具类我是放在 quick-mvc 工程的所以就直接使用了我定义的包 com.hust.hui因为没啥通用性就给出本机测试的演示图好了其他公众号获取更多: