包扫描器

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

    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. [LeetCode] 98. Validate Binary Search Tree 验证二叉搜索树

    Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...

  2. 《30天自制操作系统》笔记3 --- (Day2 上节)完全解析文件系统

    Day2 汇编语言学习与Makefile入门 本文仅带着思路,研究源码里关于文件系统的参数 关于day2主程序部分及更多内容,请看<30天自制操作系统>笔记 导航 发现学习中的变化 源码差 ...

  3. SpringCloud微服务实现生产者消费者以及ribbon负载均衡

    一.SpringCloud_eureka_server 1.导入依赖 <dependencies> <dependency> <groupId>junit</ ...

  4. rIoTboard学习系列

    刚在咸鱼买了块开发板,比较老了14年的,SOC为imx6solo,内核3.10,uboot2009的,准备先移植一个较新的uboot 到nxp的git下获取他们维护的uboot,网址http://gi ...

  5. Java 性能调优小技巧

    1.在知道必要之前不要优化系统 这可能是最重要的性能调整技巧之一.你应该遵循常见的最佳实践做法并尝试高效地实现用例.但是,这并不意味着在你证明必要之前,你应该更换任何标准库或构建复杂的优化. 在大多数 ...

  6. JS存取Cookies值

    这里对cookie进行了说明,也介绍了几个方法,但是我要取我存的cookie时取不到,他的方法只是针对存的  名字-值,不涉及键,所以自己写了个方法,来满足我的需求. 封装了简单存取Cookie: / ...

  7. Qt 操作SQLite数据库

    项目中通常需要采用各种数据库(如 Qracle.SQL Server.MySQL等)来实现对数据的存储.查询等功能.下面讲解如何在 Qt 中操作 SQlite 数据库. 一.SQLite 介绍 Sql ...

  8. ROS源更改

    ROS源更改 配置你的电脑使其能够安装来自 packages.ros.org 的软件,使用国内或者新加坡的镜像源,这样能够大大提高安装下载速度 sudo sh -c '. /etc/lsb-relea ...

  9. 奥展项目笔记01--不同网站,点击工具--开发人员工具F12,显示的页面怎么不一样

    开发人员工具F12,显示的页面不一样: 样式1: 样式2: 解决方案:兼容模式和极速模式的开发者工具不一样,改成极速模式就ok了.

  10. 折腾linux随笔 之 关闭Budgie默认自动隐藏应用的菜单栏 与 Gnome系桌面应用菜单无内容解决

    关闭Budgie默认自动隐藏应用菜单栏 首选项 -> 设置 -> 通用辅助功能 -> 打开 始终显示通用辅助菜单 后的开关 -> 注销桌面重新登录. done. 解决Gnome ...