Java中的包扫描(工具)
在现在好多应用场景中,我们需要得到某个包名下面所有的类, 包括我们自己在src里写的java类和一些第三方提供的jar包里的类,那么怎么来实现呢?
今天带大家来完成这件事。
先分享代码:
1.这个类是一个抽象类,对类的处理交给用户,所以就有了dealClass的抽象方法。
package com.mec.packscanner.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;
import java.util.jar.JarFile; public abstract class PackageScanner {
public PackageScanner() {} public abstract void dealClass(Class<?> klass); //扫描一般的包。
private void scanPackage(String packageName,File currentfile) {
File[] filelist = currentfile.listFiles(new FileFilter() {
//FileFilter是文件过滤器,源代码只写了一个accapt的抽象方法。
@Override
public boolean accept(File pathName) {
if(pathName.isDirectory()) { //判断是否是目录
return true;
}
return pathName.getName().endsWith(".class");
}
}); for(File file:filelist) {
if(file.isDirectory()) {
scanPackage(packageName + "." + file.getName(),file);
}else {
String fileName = file.getName().replace(".class", "");
String className = packageName + "." + fileName;
try {
Class<?> klass = Class.forName(className);//取出所有的类
if(klass.isAnnotation() //不扫描注解类、枚举类、接口和八大基本类型。
||klass.isEnum()
||klass.isInterface()
||klass.isPrimitive()) {
continue;
}
dealClass(klass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
} //扫描jar包方法。
private void scanPackage(URL url) throws IOException {
JarURLConnection urlConnection = (JarURLConnection) url.openConnection();
JarFile jarfile = urlConnection.getJarFile();
Enumeration<JarEntry> jarEntries = jarfile.entries();
while(jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
String jarName = jarEntry.getName();
if(!jarName.endsWith(".class")) {
continue;
}
String className = jarName.replace(".class", "").replaceAll("/", "."); try {
Class<?> klass = Class.forName(className);
if (klass.isAnnotation()
|| klass.isInterface()
|| klass.isEnum()
|| klass.isPrimitive()) {
continue;
}
dealClass(klass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
} //用类名扫描
public void packageScan(Class<?> klass) {
packageScan(klass.getPackage().getName());
} //用包名进行扫描
public void packageScan(String packageName) {
String packOpperPath = packageName.replace(".","/"); //线程上下文类加载器得到当前的classpath的绝对路径.(动态加载资源)
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
try {
//(Thread.currentThread().getContextClassLoader().getResource(""))
//(来得到当前的classpath的绝对路径的URI表示法。)
Enumeration<URL> resources = classloader.getResources(packOpperPath);
while(resources.hasMoreElements()) {
//先获得本类的所在位置
URL url = resources.nextElement(); //url.getProtocol()是获取URL的HTTP协议。
if(url.getProtocol().equals("jar")) {
//判断是不是jar包
scanPackage(url);
}else {
//此方法不会自动将链接中的非法字符转义。
//而在File转化成URI的时候,会将链接中的特殊字符如#或!等字符进行编码。
File file = new File(url.toURI());
if(!file.exists()) {
continue;
}
scanPackage(packageName,file);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
}
这个是抽象类,对于扫描,我们只提供扫描的工具,而定义抽象方法是往外接,通过使用者的使用来决定用类名还是包名。
对于jar包的扫描,可以进JarURLConnection类和JarFile类的源码中可以理解。
2.定义测试类,它是扫描jar包的:
package com.mec.packscanner.test; import com.mec.packscanner.core.PackageScanner; public class Test { public static void main(String[] args) {
new PackageScanner() { @Override
public void dealClass(Class<?> klass) {
System.out.println(klass.getName()); }
}.packageScan("com.mec.xml_view.core");;
} }
结果:
从结果我们可以看出把jar包中的每一个class都输出了,匿名内部类都被扫描出来了。
我们来看看普通包的结果吧:
package com.mec.packscanner.test; import com.mec.packscanner.core.PackageScanner; public class Test { public static void main(String[] args) {
new PackageScanner() { @Override
public void dealClass(Class<?> klass) {
System.out.println(klass.getName()); }
}.packageScan("com.mec.server_client.core");;
} }
对普通的包也是,这个例子除了接口,其他的都被扫描出来了。
若有漏洞,请指正!感谢您的阅读。
Java中的包扫描(工具)的更多相关文章
- java 中的包概念
Java 中的包package, 就是电脑中的文件夹.我们平时在工作中,文件太多时,都会新建文件夹进行分类管理,java 中的包也是类似的道理,当我们的类太多时,也需要进行分类管理,这时我们就会把类文 ...
- Java中带包(创建及引用)的类的编译
Java中带包(创建及引用)的类的编译与调试 java源程序的编译大家都知道,也就是cmd中到源文件所在目录下javac **.java即可,当程序中有包声明还能简简单单的直接javac **.jav ...
- 理解Java中【包】的概念
Java中用package关键字定义一个包,下面通过几个实验,理解Java中的包的概念和作用. 实验1:先看一个无包的情形 在G盘下新建一个Test.java,如图1: 写下面这些代码 <spa ...
- java中的包以及内部类的介绍
1:形式参数和返回值的问题(理解) (1)形式参数: 类名:需要该类的对象 抽象类名:需要该类的子类对象 接口名:需要该接口的实现类对象 (2)返 ...
- java中的包有那些 ???
java.util工具包java.sql数据库包java.io输入输出流包java.net网络包java.lang基础包这些是基本的包,还有一些其他的例如集合,反射等的工具包,你可以去查一下java ...
- Java中的包含义
JAVA提供了强大的应用程序接口,既JAVA类库.他包含大量已经设计好的工具类,帮助程序员进行字符串处理.绘图.数学计算和网络应用等方面的工作.下面简单介绍JAVA核心类库中常用的组建包. 1.jav ...
- java中的Arrays这个工具类你真的会用吗
Java源码系列三-工具类Arrays 今天分享java的源码的第三弹,Arrays这个工具类的源码.因为近期在复习数据结构,了解到Arrays里面的排序算法和二分查找等的实现,收益匪浅,决定研读 ...
- Java中,包的概念、常量、静态成员、继承
新建包:左上角-新建-包 命名规则(通常从大到小,方便整合不容易冲突) 例如:com.itnba.maya.test package必须在最顶行,之前不能再有其他代码 使用包: 快捷方式:使用包中的 ...
- Java中的包
包:定义包用package关键字. 1:对类文件进行分类管理. 2:给类文件提供多层名称空间. 如果生成的包不在当前目录下,需要最好执行classpath,将包所在父目录定义到classpath变量中 ...
随机推荐
- jQuery实现全选与全不选功能
初始时: 实现功能后: 实现该功能的核心代码: <script> $(function(){ $("#selectBtn").click(function(){ con ...
- 百度uid-generator源码
https://github.com/baidu/uid-generator snowflake算法 uid-generator是基于Twitter开源的snowflake算法实现的. snowfla ...
- 2018-2019-1 20189206 《Linux内核原理与分析》第七周作业
linux内核分析学习笔记 --第六章 进程的描述和进程的创建 学习重点--子进程的创建以及运行流程 进程描述和进程的创建 操作系统的三大功能--进程管理.内存管理和文件系统. 在linux内核中利用 ...
- 使用JBarcode生成一维码
需要的jar包,只有jbarcode.jar 链接: https://pan.baidu.com/s/1o9oDPB8 密码: x367 public class Main { //设置条形码高度 p ...
- fedora23安装搜狗輸入法?
1, 安裝方法, 是通過下載 repo文件, 添加repo文件, 然後通過dnf啦安裝的. repo文件地址是: fedora 的中文社區: https://www.fdzh.org/ fdzh: 就 ...
- 题解——洛谷P3812【模板】线性基
学了下线性基 使用好像并不复杂 打了板子 但是要注意位运算优先级 #include <cstdio> #include <algorithm> #include <cst ...
- 题解——code[vs] 1506 传话(传递闭包)
裸的传递闭包 直接Floyd暴力即可 #include <cstdio> #include <algorithm> #include <cstring> using ...
- (转载)C#语言开发规范
1. 命名规范a) 类[规则1-1]使用Pascal规则命名类名,即首字母要大写.eg:Class Test{...}[规则1-2]使用能够反映类功能的名词或名词短语命名类.[规则1-3]不要使用“ ...
- WEB 安全学习 一、mysql 注入漏洞
转载: https://www.cnblogs.com/cui0x01/p/8620524.html 一.Mysql数据库结构 数据库A 表名 列名 数据 数据库B 表名 列名 数据 Mysql5.0 ...
- Using git-flow to automate your git branching workflow
Using git-flow to automate your git branching workflow Vincent Driessen’s branching model is a git b ...