包扫描器

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

    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] 266. Palindrome Permutation 回文全排列

    Given a string, determine if a permutation of the string could form a palindrome. Example 1: Input: ...

  2. [LeetCode] 213. House Robber II 打家劫舍之二

    You are a professional robber planning to rob houses along a street. Each house has a certain amount ...

  3. Spring Cloud Gateway 结合配置中心限流

    前言 上篇文章我讲过复杂的限流场景可以通过扩展RedisRateLimiter来实现自己的限流策略. 假设你领导给你安排了一个任务,具体需求如下: 针对具体的接口做限流 不同接口限流的力度可以不同 可 ...

  4. 动手学深度学习7-从零开始完成softmax分类

    获取和读取数据 初始化模型参数 实现softmax运算 定义模型 定义损失函数 计算分类准确率 训练模型 小结 import torch import torchvision import numpy ...

  5. 用友U8根据客户简称/供应商简称的拼音首字母生成助记码

    用友U8+中,客户档案和供应商档案可以设置自动生成助记码,但软件只能自动根据客户全称/供应商全称生成助记码,而无法选择按简称生成助记码,这显然十分不方便,可以通过如下方式解决: 修改步骤 1.往数据库 ...

  6. luogu P2258 子矩阵 |动态规划

    题目描述 给出如下定义: 子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵. 例如,下面左图中选取第22.44行和第22.44.55列交叉 ...

  7. PHP中直接使用sql语句

    SELECT * FROM `tf_user` WHERE (`company_id` = '117' OR `other_company_ids` LIKE '%117,%' OR `other_c ...

  8. c++中获得对象类型 typeid 与 type_info

    复杂部分略去,摘录要素如下: 1.typeid是C++的关键字之一,等同于sizeof这类的操作符. 2.typeid操作符的返回结果是名为type_info的标准库类型的对象的引用(在头文件type ...

  9. 整理了八个开源的 Spring Boot 学习资源

    Spring Boot 算是目前 Java 领域最火的技术栈了,松哥年初出版的 <Spring Boot + Vue 全栈开发实战>迄今为止已经加印了 3 次,Spring Boot 的受 ...

  10. GET请求的请求参数最大长度

    在HTTP规范RFC-2616中有这样一段描述: The HTTP protocol does not place any a priori limit on the length of a URI. ...