170 lines
5.1 KiB
Java
170 lines
5.1 KiB
Java
package com.muyu.util;
|
||
|
||
import lombok.extern.log4j.Log4j2;
|
||
import org.springframework.stereotype.Component;
|
||
|
||
import java.io.*;
|
||
import java.util.Arrays;
|
||
import java.util.HashMap;
|
||
import java.util.List;
|
||
import java.util.Map;
|
||
|
||
/**
|
||
* @ClassName JavaCodeScan
|
||
* @Description 描述
|
||
* @Author YiBo.Liu
|
||
* @Date 2024/8/23 10:36
|
||
*/
|
||
@Log4j2
|
||
public class JavaCodeScan extends ClassLoader{
|
||
|
||
|
||
public static final String JAVA_SOURCE_SUF = ".java";
|
||
public static final String JAVA_BINARY_SUF = ".class";
|
||
|
||
private static final JavaCodeScan loader = new JavaCodeScan();
|
||
|
||
/**
|
||
*
|
||
* @param filePath 文件路径
|
||
* @param suf 扫描后缀
|
||
* @return
|
||
*/
|
||
public static File[] filterFileBySuf(String filePath,String suf){
|
||
//创建需要扫描的文件夹
|
||
File file = new File(filePath);
|
||
//列出所有的筛选suf结尾的文件集
|
||
//file.listFiles(筛选)
|
||
File[] childFiles = file.listFiles(new FilenameFilter() {
|
||
@Override
|
||
public boolean accept(File dir, String name) {
|
||
if(name.indexOf(suf) <= -1){
|
||
return false;
|
||
}else {
|
||
log.info("扫描到{}文件->{}",suf,name);
|
||
return true;
|
||
}
|
||
|
||
}
|
||
});
|
||
return childFiles;
|
||
}
|
||
|
||
/**
|
||
* @param pack 类所在的包名 com.muyu.bean. 后面需要带个点
|
||
* @param location 包所在路径
|
||
* @return
|
||
*/
|
||
public static Map<String, Class<?>> loadClassByLocation(String pack, String location) {
|
||
//列出所有的class文件
|
||
List<File> classFiles = JavaCodeScan.getClassFile(location);
|
||
HashMap<String, Class<?>> map = new HashMap<>();
|
||
classFiles.forEach(file -> {
|
||
String name = file.getName().substring(0, file.getName().lastIndexOf(JAVA_BINARY_SUF));
|
||
Class<?> c = loadClassByNameAndLocation(name, pack + ".", new File(location));
|
||
map.put(name, c);
|
||
});
|
||
return map;
|
||
}
|
||
|
||
|
||
/**
|
||
*自定义路径获取类的class对象
|
||
* @param name
|
||
* @param pack
|
||
* @param locationFile
|
||
* @return
|
||
*/
|
||
private static Class<?> loadClassByNameAndLocation(String name, String pack, File locationFile) {
|
||
//将class文件的数据读入到byte数组中
|
||
byte[] datas = loader.loadClassData(name, locationFile);
|
||
//通过byte数组加载Class对象
|
||
Class<?> aClass = loader.defineClass(pack + name, datas, 0, datas.length);
|
||
log.info("成功加载规则引擎 -- {}", aClass.getName());
|
||
return aClass;
|
||
}
|
||
|
||
/**
|
||
* 将文件转换成字节数组
|
||
*
|
||
* @param name 文件名称
|
||
* @param locationFile 文件
|
||
* @return
|
||
*/
|
||
public byte[] loadClassData(String name, File locationFile) {
|
||
byte[] byteArray = null;
|
||
try {FileInputStream fis = new FileInputStream(locationFile + "/" + name + JAVA_BINARY_SUF);
|
||
// 创建ByteArrayOutputStream对象
|
||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||
// 创建一个缓冲区
|
||
byte[] buffer = new byte[1024];
|
||
int length;
|
||
// 读取文件内容并写入缓冲区
|
||
while ((length = fis.read(buffer)) != -1) {
|
||
bos.write(buffer, 0, length);
|
||
}
|
||
// 将缓冲区中的内容转换为byte数组
|
||
byteArray = bos.toByteArray();
|
||
} catch (IOException e) {
|
||
log.error("[【{}】文件转换成字节数组错误]:{}", name, e.getMessage(), e);
|
||
throw new RuntimeException(e);
|
||
}
|
||
return byteArray;
|
||
}
|
||
|
||
|
||
/**
|
||
* 判断java文件类型
|
||
* @param file 文件
|
||
* @return 布尔类型的值
|
||
*/
|
||
public static Boolean isFileType(File file) {
|
||
return file.getName().endsWith(JAVA_SOURCE_SUF);
|
||
}
|
||
|
||
/**
|
||
* 判断是否为class文件类型
|
||
* @param file
|
||
* @return
|
||
*/
|
||
public static Boolean isClassFileType(File file){
|
||
return file.getName().endsWith(JAVA_BINARY_SUF);
|
||
}
|
||
|
||
/**
|
||
* 通过文件路径获取该文件夹下的所有java类型文件
|
||
* @param folderPath 文件夹路径
|
||
* @return java文件
|
||
*/
|
||
public static List<File> getJavaFiles(String folderPath) {
|
||
File folder = new File(folderPath);
|
||
if (!folder.exists()){
|
||
folder.mkdirs();
|
||
}
|
||
File[] files = folder.listFiles();
|
||
return Arrays.stream(isFilesExist(files)).filter(JavaCodeScan::isFileType).toList();
|
||
}
|
||
|
||
|
||
/**
|
||
* 通过路劲获取所有的.class文件
|
||
* @param location
|
||
* @return
|
||
*/
|
||
private static List<File> getClassFile(String location) {
|
||
File file = new File(location);
|
||
if(!file.exists()){
|
||
file.mkdirs();
|
||
}
|
||
File[] files = file.listFiles();
|
||
return Arrays.stream(isFilesExist(files)).filter(JavaCodeScan::isClassFileType).toList();
|
||
}
|
||
|
||
private static File[] isFilesExist(File[] files) {
|
||
if(files == null || files.length == 0){
|
||
throw new RuntimeException("该文件夹下没有文件");
|
||
}
|
||
return files;
|
||
}
|
||
}
|