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变量中 ...
随机推荐
- java热加载之springloaded
https://github.com/spring-projects/spring-loaded/wiki
- k8s渐进
基本命令介绍(推荐) 1. The Almighty Pause Container 2. What are Kubernetes Pods Anyway? 3.中文版官方翻译[版本2] 提供了很多 ...
- [c/c++] programming之路(1)、编写程序打开记事本、计算器等
一.命令行启动程序 通过命令行关闭程序:taskkill /f /im 程序名.exe 二.打开记事本.计算器 #include <stdlib.h> void main(){ syste ...
- 一、变量.二、过滤器(filter).三、标签(tag).四、条件分支tag.五、迭代器tag.六、自定义过滤器与标签.七、全系统过滤器(了解)
一.变量 ''' 1.视图函数可以通过两种方式将变量传递给模板页面 -- render(request, 'test_page.html', {'变量key1': '变量值1', ..., '变量ke ...
- P3899 [湖南集训]谈笑风生
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=3653 https://www.luogu.org/problemnew/show/P38 ...
- Baseline
Baseline Baselines an existing database, excluding all migrations upto and including baselineVersion ...
- First Steps: Command-line
This brief tutorial will teach how to get up and running with the Flyway Command-line tool. It will ...
- oracle 之 定时任务,存储过程和游标等语法案例
--定时任务 declare job20 number; begin sys.dbms_job.submit(job20,'test1;',sysdate,'sysdate+1'); end; --存 ...
- nginx的高可用集群
1,阿里云:SLB 2, 硬件负载均衡器(如:F5,RedWare ) 3,软件实现高可用或负载均衡.keepalived
- docker 命令随笔
如果是容器传输文件到本地的话,反过来就好了: docker cp ID全称:容器文件路径 本地路径 2.进入docker 容器 docker exec -it fw-pay-trade-serv ...