Java掃描包并加載Class類
- 類似SpringBean的掃描某個(gè)包下的類并加載;
- 指定某個(gè)包下類的實(shí)例化并進(jìn)行管理,用于快速main方法測(cè)試;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.*;
import java.util.function.Predicate;
/**
* 簡(jiǎn)易類掃描加載(只描述原理自行理解)
* 注:這里只簡(jiǎn)單加載了一層文件的,有多需求可以改寫文件處理
*
* @author caoch
*/
public class ClassScanLoad {
/**
* 掃描過(guò)濾后實(shí)例化類
*
* <pre>
* 示例:
* String scanPackage = "com.ttk.agg.cy.base.task.process";
* instanceClassByScanFilter(scanPackage, StringTextEtlProcess.class, null);
* </pre>
*
* @param scanPackage 掃描包
* @param resultCls 結(jié)果類型,同時(shí)也是過(guò)濾類型,這些類型必須繼承自某一接口或抽象類
* @param filter 過(guò)濾器
* @param <R> 實(shí)例化類型
* @return 實(shí)例化類
*/
public static <R> Set<R> instanceClassByScanFilter(String scanPackage, Class<R> resultCls, Predicate<Class<?>> filter) {
return filterAndInstanceClass(resultCls, getUrlOfScanPackage(scanPackage), filter);
}
public static <R> Set<R> filterAndInstanceClass(
Class<R> resultCls, Set<String> clsNameSet, Predicate<Class<?>> filter) {
try {
Set<R> rs = new HashSet<>();
for (String clsName : clsNameSet) {
Class<?> aClass = Class.forName(clsName);
if (resultCls.isAssignableFrom(aClass)) {
if (filter == null || filter.test(aClass)) {
Object cast = aClass.cast(aClass.newInstance());
rs.add(resultCls.cast(cast));
}
}
}
return rs;
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public static Set<String> getUrlOfScanPackage(String scanPackage) {
String scanPackageUrl = scanPackage.replace(".", "/");
Set<String> clsNameSet = new HashSet<>();
try {
Enumeration<URL> resources = ClassScanLoad.class
.getClassLoader().getResources(scanPackageUrl);
while (resources.hasMoreElements()) {
URL url = resources.nextElement();
if ("file".equals(url.getProtocol())) {
File file = new File(url.toURI());
// System.out.println(file.getPath());
if (file.exists() && file.isDirectory()) {
File[] files = file.listFiles();
if (files != null) {
for (File clsFile : files) {
if (clsFile.exists() && !clsFile.isDirectory()) {
// System.out.println(clsFile.getName());
String clsFileName = clsFile.getName();
if (clsFileName.endsWith(".class")) {
String clsUrlName = scanPackage + "." + clsFileName.replace(".class", "");
clsNameSet.add(clsUrlName);
}
}
}
}
}
}
}
return clsNameSet;
} catch (IOException | URISyntaxException e) {
throw new RuntimeException(e);
}
}
/**
* 遞歸文件夾
*/
private static List<File> fileDepth(File file, Predicate<File> fileFilter) {
List<File> list = null;
if (file.exists()) {
if (fileFilter == null || fileFilter.test(file)) {
// 是否目錄
if (file.isDirectory()) {
File[] files = file.listFiles();
if (files != null) {
list = new ArrayList<>(files.length);
for (File clsFile : files) {
List<File> depthFiles = fileDepth(clsFile, fileFilter);
if (!depthFiles.isEmpty()) {
list.addAll(depthFiles);
}
}
}
} else {
list = new ArrayList<>(1);
list.add(file);
}
}
}
if (list == null) {
list = new ArrayList<>(0);
}
return list;
}
}
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。