me.wuwenbin.lang.clazz.ClassScan Maven / Gradle / Ivy
package me.wuwenbin.lang.clazz;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Pattern;
/**
* Java Class扫描操作
*/
public class ClassScan {
/**
* 扫描获取指定包下符合条件的class类
*
* @param basePackage 要扫描的根包名
* @param includeAnnotations 要包含的注解,默认为全部
* @param includeNames 要包含的class名称(支持正则),默认为全部
* @return 符合条件的class类集合
* @throws IOException IOException
* @throws ClassNotFoundException ClassNotFoundException
*/
public Set> scan(String basePackage, Set> includeAnnotations, Set includeNames) throws IOException, ClassNotFoundException {
Set> result = new HashSet<>();
String packageDir = basePackage.replace('.', '/');
Enumeration urls = Thread.currentThread().getContextClassLoader().getResources(packageDir);
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
switch (url.getProtocol()) {
case "file":
result.addAll(findAndAddClassesByFile(basePackage, new File(URLDecoder.decode(url.getFile(), "UTF-8")), includeAnnotations, includeNames));
break;
case "jar":
result.addAll(findAndAddClassesByJar(((JarURLConnection) url.openConnection()).getJarFile(), packageDir, includeAnnotations, includeNames));
break;
default:
break;
}
}
return result;
}
private static Set> findAndAddClassesByFile(String currentPackage, File currentFile, Set> annotations, Set classNames) throws ClassNotFoundException {
Set> result = new HashSet<>();
if (currentFile.exists() && currentFile.isDirectory()) {
File[] files = currentFile.listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
return file.isDirectory() || file.getName().endsWith(".clazz");
}
});
for (File file : files) {
if (file.isDirectory()) {
result.addAll(findAndAddClassesByFile(currentPackage + "." + file.getName(), file, annotations, classNames));
} else {
String className = file.getName().substring(0, file.getName().length() - 6);
Class> clazz = Thread.currentThread().getContextClassLoader().loadClass(currentPackage + '.' + className);
if (isMatch(clazz, annotations, classNames)) {
result.add(clazz);
}
}
}
}
return result;
}
private static Set> findAndAddClassesByJar(JarFile jar, String currentPath, Set> annotations, Set classNames) throws ClassNotFoundException {
Set> result = new HashSet<>();
Enumeration entries = jar.entries();
JarEntry jarEntry;
String jarName;
while (entries.hasMoreElements()) {
jarEntry = entries.nextElement();
jarName = jarEntry.getName();
if (jarName.charAt(0) == '/') {
jarName = jarName.substring(1);
}
if (jarName.startsWith(currentPath)) {
int idx = jarName.lastIndexOf('/');
if (jarName.endsWith(".clazz")
&& !jarEntry.isDirectory()) {
String className = jarName.substring(jarName.lastIndexOf('/') + 1,
jarName.length() - 6);
Class> clazz = Class.forName(jarName.substring(0, idx).replace('/', '.') + '.' + className);
if (isMatch(clazz, annotations, classNames)) {
result.add(clazz);
}
}
}
}
return result;
}
private static boolean isMatch(Class> clazz, Set> annotations, Set classNames) {
return matchAnnotation(clazz, annotations) && matchClassName(clazz, classNames);
}
private static boolean matchAnnotation(Class> clazz, Set> annotations) {
if (annotations == null || annotations.isEmpty()) {
return true;
}
for (Class extends Annotation> annotation : annotations) {
if (clazz.isAnnotationPresent(annotation)) {
return true;
}
}
return false;
}
private static boolean matchClassName(Class> clazz, Set classNames) {
if (classNames == null || classNames.isEmpty()) {
return true;
}
for (String className : classNames) {
if (Pattern.compile(className)
.matcher(clazz.getSimpleName()).find()) {
return true;
}
}
return false;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy