perf[hotswap]: 优化了HotSwapUtils的代码结构

This commit is contained in:
jaysunxiao
2021-06-26 11:19:30 +08:00
parent 1ea73909ac
commit 174400e791
2 changed files with 101 additions and 18 deletions
@@ -1,6 +1,6 @@
package com.zfoo.hotswap.util;
import com.zfoo.protocol.exception.ExceptionUtils;
import com.zfoo.protocol.collection.ArrayUtils;
import com.zfoo.protocol.util.IOUtils;
import com.zfoo.protocol.util.StringUtils;
import javassist.ClassPool;
@@ -24,20 +24,6 @@ public abstract class HotSwapUtils {
private static final Logger logger = LoggerFactory.getLogger(HotSwapUtils.class);
private static String readClassName(byte[] bytes) {
//ByteArrayInputStream byteArrayInputStream = null;
DataInputStream dataInputStream = null;
try {
dataInputStream = new DataInputStream(new ByteArrayInputStream(bytes));
var classFile = new ClassFile(dataInputStream);
return classFile.getName().replaceAll(StringUtils.SLASH, StringUtils.PERIOD);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
IOUtils.closeIO(dataInputStream);
}
}
/**
* 热更新java文件
* jvm的启动参数,jdk11过后默认的全款更不允许连接自己,VM: -Djdk.attach.allowAttachSelf=true
@@ -47,20 +33,38 @@ public abstract class HotSwapUtils {
* @param bytes .class结尾的字节码文件
*/
public static synchronized void hotswapClass(byte[] bytes) {
if (bytes == null || bytes.length <= 0) {
if (ArrayUtils.isEmpty(bytes)) {
return;
}
var clazzName = readClassName(bytes);
Class<?> clazz = null;
try {
clazz = Class.forName(readClassName(bytes));
clazz = Class.forName(clazzName);
} catch (ClassNotFoundException e) {
logger.error(ExceptionUtils.getMessage(e));
logger.info("无法在当前项目找到[class:{}],所以忽略本次热更新", clazzName);
return;
}
hotswapClassByJavassist(clazz, bytes);
}
private static String readClassName(byte[] bytes) {
ByteArrayInputStream byteArrayInputStream = null;
DataInputStream dataInputStream = null;
try {
byteArrayInputStream = new ByteArrayInputStream(bytes);
dataInputStream = new DataInputStream(byteArrayInputStream);
var classFile = new ClassFile(dataInputStream);
return classFile.getName().replaceAll(StringUtils.SLASH, StringUtils.PERIOD);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
IOUtils.closeIO(dataInputStream, byteArrayInputStream);
}
}
private static void hotswapClassByJavassist(Class<?> clazz, byte[] bytes) {
ByteArrayInputStream byteArrayInputStream = null;
CtClass ctClass = null;
@@ -64,6 +64,85 @@ public abstract class ArrayUtils {
return array == null ? 0 : array.length;
}
/**
* isEmpty
*/
public static boolean isEmpty(boolean[] array) {
return (array == null || array.length == 0);
}
public static boolean isEmpty(byte[] array) {
return (array == null || array.length == 0);
}
public static boolean isEmpty(short[] array) {
return (array == null || array.length == 0);
}
public static boolean isEmpty(int[] array) {
return (array == null || array.length == 0);
}
public static boolean isEmpty(long[] array) {
return (array == null || array.length == 0);
}
public static boolean isEmpty(float[] array) {
return (array == null || array.length == 0);
}
public static boolean isEmpty(double[] array) {
return (array == null || array.length == 0);
}
public static boolean isEmpty(char[] array) {
return (array == null || array.length == 0);
}
public static <T> boolean isEmpty(T[] array) {
return (array == null || array.length == 0);
}
/**
* isNotEmpty
*/
public static boolean isNotEmpty(boolean[] array) {
return !isEmpty(array);
}
public static boolean isNotEmpty(byte[] array) {
return !isEmpty(array);
}
public static boolean isNotEmpty(short[] array) {
return !isEmpty(array);
}
public static boolean isNotEmpty(int[] array) {
return !isEmpty(array);
}
public static boolean isNotEmpty(long[] array) {
return !isEmpty(array);
}
public static boolean isNotEmpty(float[] array) {
return !isEmpty(array);
}
public static boolean isNotEmpty(double[] array) {
return !isEmpty(array);
}
public static boolean isNotEmpty(char[] array) {
return !isEmpty(array);
}
public static <T> boolean isNotEmpty(T[] array) {
return !isEmpty(array);
}
/**
* toList
*/