包扫描在框架中应用很广泛,在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. 启动 mysql 时报错

    通过mysql -u用户名 -p密码 的命令连接 Mysql数据库时 报错 "can't connect to local mysql serverthrough  socket'/var/ ...

  2. 2-postman批量执行接口

    1.postman环境设置与使用 1)点击设置,添加按钮 2)填写环境名称,参数 3)切换环境 4)使用环境变量,使用格式为:{{变量名}} 2.postman批量执行接口 1)选择要执行的文件夹,点 ...

  3. python多版本管理包pyenv

    前言: CentOS7  默认版本 python2.7.5 ,但是目前项目开发都是在python3的环境下,而单独编译安装python3时会出现各种异常!!! 系统默认python2.7又不能删除,否 ...

  4. 关于UIScrollView不能响应UITouch事件的解决办法

    原因是:UIView的touch事件被UIScrollView捕获了. 解决办法:让UIScrollView将事件传递过去.于是最简单的解决办法就是加一个UIScrollView的category.这 ...

  5. JMeter 教程汇总链接

    http://www.360doc.com/content/14/0318/23/16361380_361732630.shtml 可以作为入门系列教程. 尽管网页也给出了视频链接,但是我不建议看视频 ...

  6. 背水一战 Windows 10 (65) - 控件(WebView): 对 WebView 中的内容截图, 通过 Share Contract 分享 WebView 中的被选中的内容

    [源码下载] 背水一战 Windows 10 (65) - 控件(WebView): 对 WebView 中的内容截图, 通过 Share Contract 分享 WebView 中的被选中的内容 作 ...

  7. 关于Linux MongoDB的安装

    前一篇博文讲解了如何安装与配置MongoDB的windows版,本篇博文接着上一篇讲解如何在Linux系统中安装与配置MongoDB,为了演示,我问同事要了它的云服务器用于演示,当然我自己也有,但是已 ...

  8. Mac 安装微软雅黑字体

    https://www.jianshu.com/p/d8c34fff3483 1.找一台Windows电脑,打开字体文件夹C:\Windows\Fonts. 2.搜索"Calibri.微软雅 ...

  9. 理解js中的函数调用和this

    概述 这是我看typescript的时候看引用资源看到的,原文在这里:Understanding JavaScript Function Invocation and "this" ...

  10. JavaScript中子类调用父类方法的实现

    一.前言 最近在项目中,前端框架使用JavaScript面向对象编程,遇到了诸多问题,其中最典型的问题就是子类调用父类(super class)同名方法,也就是如C#中子类中调用父类函数base.** ...