【Java】包,jar包的扫描
包扫描在框架中应用很广泛,在spring中,通过给自己的类加注解的方式,利用spring的包扫描,完成依赖注入。
package com.test.package_scanner.core; import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Enumeration;
import java.util.jar.JarEntry; public abstract class PackageScanner { public PackageScanner() {
} // scanPackage方法的重载
public void scanPackage(Class<?> klass) {
scanPackage(klass.getPackage().getName());
} public void scanPackage(String packageName) {
// 将包名称转换为路径名称的形式
String packagePath = packageName.replace(".", "/"); try {
// 由类加载器得到URL的枚举
Enumeration<URL> resources = Thread.currentThread()
.getContextClassLoader()
.getResources(packagePath); while (resources.hasMoreElements()) {
URL url = resources.nextElement(); // 处理jar包
if (url.getProtocol().equals("jar")) {
parse(url);
} else {
File file = new File(url.toURI()); if (file.exists()) {
// 处理普通包
parse(file, packageName);
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
// 抽象方法,由用户自行处理扫描到的类
public abstract void dealClass(Class<?> klass); // jar包的扫描
private void parse(URL url) throws IOException {
Enumeration<JarEntry> jarEntries = ((JarURLConnection) url.openConnection())
.getJarFile().entries(); while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
String jarName = jarEntry.getName(); if (!jarEntry.isDirectory() && jarName.endsWith(".class")) {
// 将文件路径名转换为包名称的形式
dealClassName(jarName.replace("/", ".").replace(".class", ""));
}
}
} // 普通包的扫描
private void parse(File curFile, String packageName) {
File[] fileList = curFile.listFiles(new FileFilter() {
// 筛选文件夹和class文件,其余文件不处理
@Override
public boolean accept(File pathname) {
return pathname.isDirectory() || pathname.getName().endsWith(".class");
}
}); // 目录就是一颗树,对树进行递归,找到class文件
for (File file : fileList) {
String fileName = file.getName();
if (file.isDirectory()) {
parse(file, packageName + "." + fileName);
} else {
String className = packageName + "." + fileName.replace(".class", "");
dealClassName(className);
}
}
} // 将找到的class文件生成类对象
private void dealClassName(String className) {
try {
Class<?> klass = Class.forName(className); // 注解、接口、枚举、原始类型不做处理
if (!klass.isAnnotation()
&& !klass.isInterface()
&& !klass.isEnum()
&& !klass.isPrimitive()) {
dealClass(klass);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} }
对如下目录扫描

package com.test.package_scanner.demo;
import com.test.package_scanner.core.PackageScanner;
public class Demo {
public static void main(String[] args) {
new PackageScanner() {
@Override
public void dealClass(Class<?> klass) {
System.out.println(klass);
}
}.scanPackage("com");
}
}
结果如下

【Java】包,jar包的扫描的更多相关文章
- java 执行 jar 包中的 main 方法
java 执行 jar 包中的 main 方法 通过 OneJar 或 Maven 打包后 jar 文件,用命令: java -jar ****.jar执行后总是运行指定的主方法,如果 jar 中有多 ...
- Java常用jar包用途
Java常用jar包用途: USAGE INDEX JAR NAME USAGE 1 ASM asm-2.2.3.jar ASM字节码库 2 ASM asm-commons-2.2.3.jar ASM ...
- (转)java 从jar包中读取资源文件
(转)java 从jar包中读取资源文件 博客分类: java 源自:http://blog.csdn.net/b_h_l/article/details/7767829 在代码中读取一些资源文件 ...
- Python3.5调用Java的jar包
声明:这个是在一个博客上看到的,过了俩星期了突然找不到原博客了,如果原来的博主看到,请联系我删除~ 主要是怕自己忘记,所以在此记录: 环境 Python3.5+JDK1.8 安装命令:python3 ...
- Java axis2.jar包详解及缺少jar包错误分析
Java axis2.jar包详解及缺少jar包错误分析 一.最小开发jar集 axis2 开发最小jar包集: activation-1.1.jar axiom-api-1.2.13.jar ax ...
- java执行jar包出错:Unable to access jarfile
java执行jar包出错:Unable to access jarfile 错误的原因有多种: 1.一般都是路径不正确.在Windows中,正确的路径类似于: java -jar "D:\W ...
- java 生成jar包并保留注释
java 生成jar包并保留注释 CreationTime--2018年7月17日08点32分 Author:Marydon 1.选中java项目-->右键-->Export: 2.去 ...
- 杂项-Java:jar 包与 war 包介绍与区别
ylbtech-杂项-Java:jar 包与 war 包介绍与区别 1.返回顶部 1. 做Java开发,jar包和war包接触的挺多的,有必要对它们做一个深入的了解,特总结整理如下: 1.jar包的介 ...
- Java 的JAR包、EAR包、WAR包区别
一.WAR包 WAR(Web Archive file) 网络应用程序文件,是与平台无关的文件格式,它允许将许多文件组合成一个压缩文件.WAR专用于Web方面.大部分的JAVA WEB工程,都是打成W ...
- 将java打jar包成linux后台服务service
将java打jar包成linux后台服务service 第一步:将java程序打成jar包 build.gradle配置文件中加spring-boot-gradle-plugin插件,具体配置如下(配 ...
随机推荐
- SSM_CRUD新手练习(9)显示分页数据
我们已经做好了用来显示数据的分页模板,现在只需要将我们从后台取出的数据填充好,显示出来. 我们使用<c:forEach>标签循环取出数据,所以需要先导入JSTL标签库 <%@ tag ...
- 进程池、tornado、字体
协程: import grequests from fake_useragent import UserAgent urls=[f'http://bir删d.so/search?page={p ...
- 微信公众号UX分析—— 学生作业小结
1. 不足: 1. 权威性:个人帐号,显得不够正式. 2. 排版问题: + 没有必要的外接端口,界面设计极度缺少排版.哪怕是个人公众号都不至于如此,更何况这是一个学校的教务平台. 3. 反应不及时或无 ...
- Hessian学习(springboot环境)
Hessian介绍: Hessian是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能. 相比WebService,Hessian更简单.快捷.采用的是二进制RPC协议 ...
- poj2699
神题目=神题解+神读入 题意:n个人比赛, 两两比,共n*(n-1), 赢得1分, n<=10(这给了我们枚举的暗示),如果一个人打败了所有比自己分数高的人, 或者他本身就是分数最高的, 那么他 ...
- 关于Android的Service知识点,你知道吗?
目录 学习Service相关知识点: 概述: Service生命周期: Service的基本用法: 服务. 问:达叔,今日工作累吗? 答:累啊,那么问你,你知道Android中的 Service(服务 ...
- Swift5 语言指南(八) 控制流
Swift提供了各种控制流程语句.这些包括while多次执行任务的循环; if,guard和switch基于特定条件执行不同代码分支的语句; 和语句,如break和continue对执行流在你的代码转 ...
- redis 乐观锁实践秒杀
需求:有一个标(理解成抢红包也行,accountBalance预赋值1000元),大家可以抢购,每个用户抢购成功后,更新最后标的总数,在并发情况下,使用redis的乐观锁,保证更新标总值正确性,先往r ...
- Python必会的单元测试框架 —— unittest
用Python搭建自动化测试框架,我们需要组织用例以及测试执行,这里博主推荐Python的标准库——unittest. unittest是xUnit系列框架中的一员,如果你了解xUnit的其他成员,那 ...
- thymeleaf 的使用
thymeleaf 语法详解1.变量输出: th:text :在页面中输出某个值 th:value :将一个值放到input标签中的value中.2.判断字符串是否为空 ①:调用内置对象一定要用# ② ...