All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.feingto.cloud.kit.ClassKit Maven / Gradle / Ivy
package com.feingto.cloud.kit;
import com.google.common.collect.Lists;
import javassist.*;
import javassist.bytecode.CodeAttribute;
import javassist.bytecode.LocalVariableAttribute;
import javassist.bytecode.MethodInfo;
import org.springframework.util.StringUtils;
import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.stream.Collectors;
/**
* Class 工具类
*
* @author longfei
*/
public class ClassKit {
/**
* 判断类是否存在
*
* @param className 类名
* @return boolean
*/
public static boolean isExist(String className) {
Class> clazz = null;
try {
clazz = Class.forName(className);
} catch (ClassNotFoundException ignored) {
}
return Objects.nonNull(clazz);
}
/**
* 判断是否基本类型
*
* @param clazz Class
* @return boolean
*/
public static boolean isJavaBasicType(Class> clazz) {
return Objects.nonNull(clazz) && (clazz.isPrimitive() || Number.class.isAssignableFrom(clazz) || Character.class.isAssignableFrom(clazz) || Boolean.class.isAssignableFrom(clazz) || CharSequence.class.isAssignableFrom(clazz) || Enum.class.isAssignableFrom(clazz) || Date.class.isAssignableFrom(clazz) || Calendar.class.isAssignableFrom(clazz));
}
/**
* 判断指定的类是否为Collection(或者其子类或者其子接口)
*
* @param clazz Class
* @return boolean
*/
public static boolean isCollection(Class> clazz) {
return Objects.nonNull(clazz) && Collection.class.isAssignableFrom(clazz);
}
/**
* 判断指定的类是否为Map(或者其子类或者其子接口)
*
* @param clazz Class
* @return boolean
*/
public static boolean isMap(Class> clazz) {
return Objects.nonNull(clazz) && Map.class.isAssignableFrom(clazz);
}
/**
* 判断指定的类是否为Java基本类型的数组
*
* @param clazz Class
* @return boolean
*/
public static boolean isPrimitiveArray(Class> clazz) {
return (clazz == byte[].class || (clazz == short[].class || (clazz == int[].class || (clazz == long[].class || (clazz == char[].class || (clazz == float[].class || (clazz == double[].class || clazz == boolean[].class)))))));
}
/**
* 判断指定的类是否为Java基本类型的数组
*
* @param clazz Class
* @return boolean
*/
public static boolean isPrimitiveWrapperArray(Class> clazz) {
return (clazz == Byte[].class || (clazz == Short[].class || (clazz == Integer[].class || (clazz == Long[].class || (clazz == Character[].class || (clazz == Float[].class || (clazz == Double[].class || clazz == Boolean[].class)))))));
}
/**
* 获取包括该类本身但不包含java.lang.Object的所有超类
*
* @param clazz Class
* @return 超类数组
*/
public static Class>[] getAllSupperClass(Class> clazz) {
List> classes = new ArrayList<>();
getAllSupperClass(classes, clazz);
return classes.toArray(new Class[0]);
}
private static void getAllSupperClass(List> classes, Class> clazz) {
if (!clazz.equals(Object.class)) {
classes.add(clazz);
getAllSupperClass(classes, clazz.getSuperclass());
}
}
/**
* 获取该类所有实现的接口数组
*
* @param clazz Class
* @return 该类所有的实现接口数组
*/
public static Class>[] getAllInterface(Class> clazz) {
List> classes = new ArrayList<>();
Class>[] interfaces = clazz.getInterfaces();
for (Class> interfaceClazz : interfaces) {
classes.add(interfaceClazz);
getAllSupperInterface(classes, interfaceClazz);
}
return classes.toArray(new Class>[0]);
}
private static void getAllSupperInterface(List> classes, Class> clazz) {
if (!clazz.equals(Object.class)) {
Class>[] interfaces = clazz.getInterfaces();
for (Class> interfaceClazz : interfaces) {
classes.add(interfaceClazz);
getAllSupperInterface(classes, interfaceClazz);
}
}
}
/**
* 获取包括该类本身以及所有超类(不含java.lang.Object)和实现的接口中定义的属性
*
* @param clazz Class
* @return 属性数组
*/
public static Field[] getAllField(Class> clazz) {
List fieldList = new ArrayList<>();
Class>[] supperInterfaces = getAllSupperClass(clazz);
for (Class> aClazz : supperInterfaces) {
fieldList.addAll(Lists.newArrayList(aClazz.getDeclaredFields()));
}
supperInterfaces = getAllInterface(clazz);
for (Class> aInterface : supperInterfaces) {
fieldList.addAll(Lists.newArrayList(aInterface.getDeclaredFields()));
}
return fieldList.toArray(new Field[0]);
}
/**
* 获取该类中所有字段
*
* @param clazz Class
* @return 属性数组
*/
public static Field[] getFields(Class> clazz) {
return new ArrayList<>(Lists.newArrayList(clazz.getDeclaredFields())).toArray(new Field[0]);
}
/**
* 得到方法参数名称和方法参数值
* 注:类里面同名方法会解析第一个
*
* @param clazz 当前类
* @param clazzName 方法类名
* @param methodName 方法名
* @param args 方法参数
* @return Map
*/
public static Map getFieldMap(Class> clazz, String clazzName, String methodName, Object[] args) throws NotFoundException {
Map map = new HashMap<>();
ClassPool pool = ClassPool.getDefault();
ClassClassPath classPath = new ClassClassPath(clazz);
pool.insertClassPath(classPath);
CtClass cc = pool.get(clazzName);
CtMethod cm = cc.getDeclaredMethod(methodName);
MethodInfo methodInfo = cm.getMethodInfo();
CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
if (Objects.isNull(attr)) {
throw new RuntimeException();
}
int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
for (int i = 0; i < cm.getParameterTypes().length; i++) {
map.put(attr.variableName(i + pos), args[i]);
}
return map;
}
/**
* 获取启用元注解clazz的全部类
*
* @param packageName 包路径
* @param clazz 元注解类
* @return 类集合
*/
public static Set> getClassesByAnnotation(String packageName, Class extends Annotation> clazz) {
return getClasses(packageName).stream()
.filter(clz -> clz.isAnnotationPresent(clazz))
.collect(Collectors.toSet());
}
/**
* 从包package中获取所有的Class
*
* @param packageName 包路径
* @return 类集合
*/
public static Set> getClasses(String packageName) {
// 第一个class类的集合
Set> classes = new LinkedHashSet<>();
// 获取包的名字, 并进行替换
String packageDirName = packageName.replace('.', '/');
// 定义一个枚举的集合, 并进行循环来处理这个目录下的things
Enumeration dirs;
try {
dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
while (dirs.hasMoreElements()) {
URL url = dirs.nextElement();
String protocol = url.getProtocol();
// 如果是以文件的形式保存在服务器上
if ("file".equals(protocol)) {
// 获取包的物理路径
String filePath = EncodeKit.urlDecode(url.getFile());
// 以文件的方式扫描整个包下的文件, 并添加到集合中
getClassesByPackage(packageName, filePath, true, classes);
} else if ("jar".equals(protocol)) {
// 如果是jar包文件, 定义一个JarFile
JarFile jar;
try {
// 获取jar
jar = ((JarURLConnection) url.openConnection()).getJarFile();
// 从jar包, 得到一个枚举类
Enumeration entries = jar.entries();
// 同样的进行循环迭代
while (entries.hasMoreElements()) {
// 获取jar里的一个实体, 可以是目录和一些jar包里的其他文件, 如META-INF等文件
JarEntry entry = entries.nextElement();
String name = entry.getName();
if (name.charAt(0) == '/') {
name = name.substring(1);
}
// 如果前半部分和定义的包名相同
if (name.startsWith(packageDirName)) {
int idx = name.lastIndexOf('/');
// 如果以"/"结尾, 则是一个包
if (idx != -1) {
// 获取包名, 把"/"替换成"."
packageName = name.substring(0, idx).replace('/', '.');
}
// 如果是一个.class文件, 并且不是目录
if (name.endsWith(".class") && !entry.isDirectory()) {
// 去掉后面的".class", 获取真正的类名
String className = name.substring(packageName.length() + 1, name.length() - 6);
try {
classes.add(Class.forName(packageName + '.' + className));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
return classes;
}
/**
* 以文件的形式扫描包下的所有Class并加载到上下文
*
* @param packageName 包名
* @param packagePath 存放类文件的包目录路径
* @param recursive 是否循环迭代
* @param classes 类集合
*/
public static void getClassesByPackage(String packageName, String packagePath, final boolean recursive, Set> classes) {
File dir = new File(packagePath);
if (dir.exists() && dir.isDirectory()) {
// 自定义过滤规则, 如果可以循环(包含子目录)或以.class结尾的文件(编译好的java类文件)
File[] dirfiles = dir.listFiles(file -> recursive && file.isDirectory() || file.getName().endsWith(".class"));
if (Objects.nonNull(dirfiles)) {
for (File file : dirfiles) {
if (file.isDirectory()) {
getClassesByPackage(packageName + "." + file.getName(), file.getAbsolutePath(), recursive, classes);
} else {
// 如果是java类文件, 去掉后面的.class, 只留下类名
String className = file.getName().substring(0, file.getName().length() - 6);
try {
classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName + '.' + className));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
}
}
/**
* 读取目录下的jar文件中指定目录下面的全部class
*
* @param packagePath jar文件目录路径
* @param packageName jar文件里的包名:格式"/xxx/yyy"
* @return 类集合
*/
public static Set> getClassesByJar(String packagePath, String packageName) {
Set> classes = new HashSet<>();
File dir = new File(packagePath);
if (dir.exists() && dir.isDirectory()) {
File[] dirfiles = dir.listFiles(file -> file.getName().endsWith(".jar"));
if (Objects.nonNull(dirfiles)) {
for (File file : dirfiles) {
classes.addAll(getClassesByJar(file, packageName));
}
}
}
return classes;
}
/**
* 读取jar文件中指定目录下面的全部class
*
* @param file jar文件
* @param packageName jar文件里的包名"com.feingto.cloud.admin.plugins"
* @return 类集合
*/
public static Set> getClassesByJar(File file, String packageName) {
packageName = packageName.replace('.', '/');
Set> classes = new HashSet<>();
try {
JarFile jarFile = new JarFile(file);
List entryList = new ArrayList<>();
Enumeration entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
if (entry.getName().endsWith(".class") && (
StringUtils.hasText(packageName) && entry.getName().startsWith(packageName)
|| StringUtils.isEmpty(packageName)
)) {
entryList.add(entry);
}
}
for (JarEntry entry : entryList) {
String className = entry.getName().replace('/', '.');
if (className.endsWith(".class") && !entry.isDirectory()) {
className = className.substring(0, className.length() - 6);
try {
classes.add(Thread.currentThread().getContextClassLoader().loadClass(className));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
return classes;
}
}