refactor: optimize LambdaUtil performance

This commit is contained in:
Michael Yang 2024-05-30 11:52:25 +08:00
parent eb663b3518
commit 475c90c13b

View File

@ -31,10 +31,12 @@ public class LambdaUtil {
private LambdaUtil() {
}
private static final Map<Class<?>, SerializedLambda> lambdaMap = new ConcurrentHashMap<>();
private static final Map<String, Class<?>> classMap = new ConcurrentHashMap<>();
private static final Map<Class<?>, String> fieldNameMap = new ConcurrentHashMap<>();
private static final Map<Class<?>, Class<?>> implClassMap = new ConcurrentHashMap<>();
private static final Map<Class<?>, QueryColumn> queryColumnMap = new ConcurrentHashMap<>();
public static <T> String getFieldName(LambdaGetter<T> getter) {
return MapUtil.computeIfAbsent(fieldNameMap, getter.getClass(), aClass -> {
SerializedLambda lambda = getSerializedLambda(getter);
// 兼容 Kotlin KProperty Lambda 解析
if (lambda.getCapturedArgCount() == 1) {
@ -49,12 +51,15 @@ public class LambdaUtil {
}
String methodName = lambda.getImplMethodName();
return StringUtil.methodToProperty(methodName);
});
}
public static <T> Class<?> getImplClass(LambdaGetter<T> getter) {
return MapUtil.computeIfAbsent(implClassMap, getter.getClass(), aClass -> {
SerializedLambda lambda = getSerializedLambda(getter);
return getImplClass(lambda, getter.getClass().getClassLoader());
});
}
@ -69,17 +74,18 @@ public class LambdaUtil {
public static <T> QueryColumn getQueryColumn(LambdaGetter<T> getter) {
return MapUtil.computeIfAbsent(queryColumnMap, getter.getClass(), aClass -> {
ClassLoader classLoader = getter.getClass().getClassLoader();
SerializedLambda lambda = getSerializedLambda(getter);
Class<?> entityClass = getImplClass(lambda, classLoader);
TableInfo tableInfo = TableInfoFactory.ofEntityClass(entityClass);
String propertyName = getFieldName(getter);
return tableInfo.getQueryColumnByProperty(propertyName);
});
}
private static SerializedLambda getSerializedLambda(Serializable getter) {
return MapUtil.computeIfAbsent(lambdaMap, getter.getClass(), aClass -> {
try {
Method method = getter.getClass().getDeclaredMethod("writeReplace");
method.setAccessible(Boolean.TRUE);
@ -87,19 +93,16 @@ public class LambdaUtil {
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
private static Class<?> getImplClass(SerializedLambda lambda, ClassLoader classLoader) {
String implClass = getImplClassName(lambda);
return MapUtil.computeIfAbsent(classMap, implClass, s -> {
try {
return Class.forName(s.replace("/", "."), true, classLoader);
return Class.forName(implClass.replace("/", "."), true, classLoader);
} catch (ClassNotFoundException e) {
throw FlexExceptions.wrap(e);
}
});
}
private static String getImplClassName(SerializedLambda lambda) {