包扫描器

获取一个包下的所有类,然后使用默认的类加载器加载到内存中

    public static List<Class<?>> scanByPackage(String packageName) throws IOException, URISyntaxException {
//我们传入的包名都是 "com.stdpain.xx" 这种的需要替换成 "com/stdpain/xx"
String packagePath = packageName.replace(".", "/");
//获取当前类加载器
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
List<Class<?>> classes = new ArrayList<>();
Enumeration<URL> resources = classLoader.getResources(packagePath);
while (resources.hasMoreElements()) {
//获取 url
URL url = resources.nextElement();
//判断url是不是一个 jar:// 类型的url 不同的url需要有不同的处理方式,我们默认只有文件系统和jar
if (url.getProtocol().equals("jar")) {
//handle jar Package
System.out.println(url);
List<Class<?>> scanedClasses = packageJarScan(url);
classes.addAll(scanedClasses);
} else {
File file = new File(url.toURI());
if (!file.exists()) {
System.out.println("file not exists = " + file.getAbsolutePath());
continue;
}
System.out.println("scan:" + file.getAbsolutePath());
//handle file package
List<Class<?>> scanedClasses = packageScan(file, packageName);
classes.addAll(scanedClasses);
}
}
return classes;
}

Jar 处理

    public static List<Class<?>> packageJarScan(URL url) throws IOException {
//强制类型转换
JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();
JarFile jarFile = jarURLConnection.getJarFile();
Enumeration<JarEntry> jarEntries = jarFile.entries();
List<Class<?>> classes = new ArrayList<>();
//遍历判断
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
String jarName = jarEntry.getName();
if (jarEntry.isDirectory() || !jarName.endsWith(".class")) {
continue;
}
String className = jarName.replace(".class", "").replace("/", ".");
try {
System.out.println(className);
Class<?> clazz = Class.forName(className);
classes.add(clazz);
System.out.println(className + "->load:success");
} catch (ClassNotFoundException e) {
// e.printStackTrace();
System.out.println("e.getMessage() = " + e.getMessage());
}
}
return classes;
}

文件系统直接递归处理目录就可以

    public static List<Class<?>> packageScan(File curFile, String packageName) {
ArrayList<Class<?>> classes = new ArrayList<>();
if (!curFile.isDirectory()) {
return classes;
}
File[] files = curFile.listFiles();
for (File file : files) {
if (file.isFile() && file.getName().endsWith(".class")) {
String fileName = file.getName().replace(".class", "");
String className = packageName + "." + fileName;
try {
Class<?> clazz = Class.forName(className);
classes.add(clazz);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} else if (file.isDirectory()) {
//如果是个目录那么就递归处理目录
classes.addAll(packageScan(file, packageName + "." + file.getName()));
}
}
return classes;
}

包扫描器有什么用

Spring 中通过注解配置 就是通过包扫描器下每个class是否包含某些注解

Java 包扫描器的更多相关文章

  1. 全栈的自我修养: 0005 Java 包扫描实现和应用(Jar篇)

    全栈的自我修养: 0005 Java 包扫描实现和应用(Jar篇) It's not the altitude, it's the attitude. 决定一切的不是高度而是态度. Table of ...

  2. Spring利器之包扫描器

    在学习Spring这门技术中为了大大减少applicationContext.xml配置的代码量于是有了包扫描器. 闲话不多说我们马上来实现一下吧 示例架构如下: 第一步我们先来修改我们的配置appl ...

  3. Android 虚拟机Dalvik、Android各种java包功能、Android相关文件类型、应用程序结构分析、ADB

    Android虚拟机Dalvik Dalvik冲击 随着Google 的AndroidSDK 的发布,关于它的API 以及在移动电话领域所带来的预期影响这些方面的讨论不胜枚举.不过,其中的一个话题在J ...

  4. 在Eclipse工具里创建maven的web工程,在建立src/main/java包出现The folder is already a source folder.解决

    1. 与创建普通java工程一样,点击右键找到New菜单,在弹出的界面输入maven ---->>点击maven Project------>>点击next 2  进入下一个界 ...

  5. android工程gen目录中R.java包名是怎么确定

    新建一个工程,包名用的com.mythroad.adskiller, 后来觉得不好,又改成com.mythroad.adsinscepter,但是我发现gen下的R.java文件的包名还是原来的com ...

  6. JavaSE复习日记 : java包机制

    这里是第一个文件,命名为JavaSE_01.java,我在这个文件里面声明了一个m1()方法,通过包机制,我将在另外一个文件夹里访问这个文件里的东西,确切的说是访问这个文件生成的一个class文件; ...

  7. 6、Java包的命名与划分

    6.包的命名与划分 (一)使用Java包的目的 在了解做一件事之前,需要了解做这件事的目的.而使用Java包的目的大概如下: 1    对类进行归类,便于开发查找. 2    将软件在代码层面上模块化 ...

  8. 列出JDK中常用的Java包

    列出JDK中常用的Java包 1.java.lang 2.java.sql 3.java.io 4.java.math 5.java.text 6.java.net 7.java.util 8.jav ...

  9. Android数据库框架——ORMLite轻量级的对象关系映射(ORM)Java包

    Android数据库框架--ORMLite轻量级的对象关系映射(ORM)Java包 事实上,我想写数据库的念头已经很久了,在之前写了一个答题系统的小项目那只是初步的带了一下数据库,数据库是比较强大的, ...

随机推荐

  1. C++版本 ORM 访问数据库之ODB 的oracle Demo测试(二)

    有上篇文章已经说了odb的环境编译, 现在直接拿来给的例子进行数据库的增删改查操作测试 1. ODB访问oracle数据库_ 插入操作(insert) 直接运行上篇编译好的exe文件会出现如下错误 错 ...

  2. thinkphp5.0 - nginx 配置

    上面介绍的是 thinkphp url 的访问方式,按照上面的访问方式配置nginx服务器配置,如下所示: server { listen 8090; server_name localhost 17 ...

  3. oracle--LGWR

    一,LGWR功能 日志写进程(日志写比数据写更重要),因为内存中的数据一断电就消 失,要做数据的回滚.前滚只能依靠日志文件.log buffer 只是缓冲日志写 二,触发机制 ) 提交命令:commi ...

  4. kubernetes实战(九):k8s集群动态存储管理GlusterFS及使用Heketi扩容GlusterFS集群

    1.准备工作 所有节点安装GFS客户端 yum install glusterfs glusterfs-fuse -y 如果不是所有节点要部署GFS管理服务,就在需要部署的节点上打上标签 [root@ ...

  5. ASP.NET的MVC请求处理流程

    1.用户打开浏览器,在地址栏输入某个网址的URL并回车,浏览器便开始像该URL指定的服务器发起HTTP请求 .2.服务器的网站服务系统(IIS)接收到该请求,先检查自己是否认识该类请求,如果认识就直接 ...

  6. 调试MATLAB代码

    1.在子函数设置的断点,在运行时,不起作用: 因为在主函数开始时,使用了clear all,在运行时,会把断点给删除.

  7. 【springboot】【jasypt】加密密码

    springboot的版本是 Spring Boot :: (v2.1.5.RELEASE) 依赖 <dependency> <groupId>com.github.ulise ...

  8. windows10安装ubuntu双系统教程(初稿)

    windows10安装ubuntu双系统教程(绝对史上最详细) Win10 Ubuntu16.04/Ubuntu18.04双系统完美安装 Windows10+Ubuntu18.04双系统安装成功心得( ...

  9. Java8 新特性 Steam() 中间有状态操作

    中间有状态操作 Java8 新特性 Stream 练习实例   中间操作,就是把数据处理成自己想要的类型,并且有状态操作,是在所有的数据基础上进行操作的.比如dictinct(去重),sorted(排 ...

  10. KVM虚拟机典型配置文件xml

    <domain type='kvm'> <name>vm64-1</name> //虚拟机名称 <memory unit='MiB'>2300</ ...