包扫描在框架中应用很广泛,在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包的扫描的更多相关文章

  1. java 执行 jar 包中的 main 方法

    java 执行 jar 包中的 main 方法 通过 OneJar 或 Maven 打包后 jar 文件,用命令: java -jar ****.jar执行后总是运行指定的主方法,如果 jar 中有多 ...

  2. 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 ...

  3. (转)java 从jar包中读取资源文件

    (转)java 从jar包中读取资源文件 博客分类: java   源自:http://blog.csdn.net/b_h_l/article/details/7767829 在代码中读取一些资源文件 ...

  4. Python3.5调用Java的jar包

    声明:这个是在一个博客上看到的,过了俩星期了突然找不到原博客了,如果原来的博主看到,请联系我删除~ 主要是怕自己忘记,所以在此记录: 环境 Python3.5+JDK1.8 安装命令:python3 ...

  5. Java axis2.jar包详解及缺少jar包错误分析

    Java  axis2.jar包详解及缺少jar包错误分析 一.最小开发jar集 axis2 开发最小jar包集: activation-1.1.jar axiom-api-1.2.13.jar ax ...

  6. java执行jar包出错:Unable to access jarfile

    java执行jar包出错:Unable to access jarfile 错误的原因有多种: 1.一般都是路径不正确.在Windows中,正确的路径类似于: java -jar "D:\W ...

  7. java 生成jar包并保留注释

      java 生成jar包并保留注释 CreationTime--2018年7月17日08点32分 Author:Marydon 1.选中java项目-->右键-->Export: 2.去 ...

  8. 杂项-Java:jar 包与 war 包介绍与区别

    ylbtech-杂项-Java:jar 包与 war 包介绍与区别 1.返回顶部 1. 做Java开发,jar包和war包接触的挺多的,有必要对它们做一个深入的了解,特总结整理如下: 1.jar包的介 ...

  9. Java 的JAR包、EAR包、WAR包区别

    一.WAR包 WAR(Web Archive file) 网络应用程序文件,是与平台无关的文件格式,它允许将许多文件组合成一个压缩文件.WAR专用于Web方面.大部分的JAVA WEB工程,都是打成W ...

  10. 将java打jar包成linux后台服务service

    将java打jar包成linux后台服务service 第一步:将java程序打成jar包 build.gradle配置文件中加spring-boot-gradle-plugin插件,具体配置如下(配 ...

随机推荐

  1. 可遇不可求的Question之MySQL系统变量interactive_timeout 与 wait_timeout 篇

    mysql>show variables like '%timeout'; 打印结果如下: +----------------------------+-------+ | Variable_n ...

  2. http响应头里没有或者有content-length的几种可能性

    对于http的请求返回结果要进行内容的长度校验主要有两种方式,二者互斥使用 1.客户端在http头(head)加Connection:keep-alive时,服务器的response是Transfer ...

  3. iostat 命令详解

    前言 话说搞运维的人没有两把"刷子",都不好意思上服务器操作.还好,我还不是搞运维的,我一直都自诩是开发人员,奈何现在的东家运维人员"水"的一比,还要我这个自诩 ...

  4. 分布式任务调度系统xxl-job搭建

    为解决分布式环境下定时任务的可靠性,稳定性,只执行一次的特性,我找到了个大众点评开源的分布式调度任务解决完整系统,下面我将一步步深入解读该系统,从基本的使用到源码的探究 下载 https://gith ...

  5. 人生苦短之---认识Python

    认识 Python 人生苦短,我用 Python —— Life is short, you need Python 目标 Python 的起源 为什么要用 Python? Python 的特点 Py ...

  6. LeetCode:111_Minimum Depth of Binary Tree | 二叉树的最小深度 | Easy

    要求:此题正好和Maximum Depth of Binary Tree一题是相反的,即寻找二叉树的最小的深度值:从根节点到最近的叶子节点的距离. 结题思路:和找最大距离不同之处在于:找最小距离要注意 ...

  7. 13-部署traefik-ingress插件

    Kubernetes traefik ingress安装 Ingress简介 如果你还不了解,ingress是什么,可以先看下我翻译的Kubernetes官网上ingress的介绍Kubernetes ...

  8. scrapy爬虫--苏宁图书

    实现业务逻辑如下: 1. 创建scrapy项目,并生成 爬虫2. 在suning.py中实现Schedul 和 Spider业务逻辑3. 修改start_urls为正确的初始请求地址4. 构造pars ...

  9. MathWorks官方消息:神经网络工具箱不能编译

    各位会员大家好,大家关心的问题,我已经大部分得到答案. 10月25号-27号我访问了MathWorks公司在波士顿的总部,大家经常关心的问题,我大部分都得到了答案. 关于神经网络工具箱,我与Matla ...

  10. 3.spring环境搭建

    1. 导入jar     1.1 四个核心包一个日志包(commons-logging)