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,30 +31,35 @@ public class LambdaUtil {
private LambdaUtil() { private LambdaUtil() {
} }
private static final Map<Class<?>, SerializedLambda> lambdaMap = new ConcurrentHashMap<>(); private static final Map<Class<?>, String> fieldNameMap = new ConcurrentHashMap<>();
private static final Map<String, Class<?>> classMap = 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) { public static <T> String getFieldName(LambdaGetter<T> getter) {
SerializedLambda lambda = getSerializedLambda(getter); return MapUtil.computeIfAbsent(fieldNameMap, getter.getClass(), aClass -> {
// 兼容 Kotlin KProperty Lambda 解析 SerializedLambda lambda = getSerializedLambda(getter);
if (lambda.getCapturedArgCount() == 1) { // 兼容 Kotlin KProperty Lambda 解析
Object capturedArg = lambda.getCapturedArg(0); if (lambda.getCapturedArgCount() == 1) {
try { Object capturedArg = lambda.getCapturedArg(0);
return (String) capturedArg.getClass() try {
.getMethod("getName") return (String) capturedArg.getClass()
.invoke(capturedArg); .getMethod("getName")
} catch (Exception e) { .invoke(capturedArg);
// 忽略这个异常使用其他方式获取方法名 } catch (Exception e) {
// 忽略这个异常使用其他方式获取方法名
}
} }
} String methodName = lambda.getImplMethodName();
String methodName = lambda.getImplMethodName(); return StringUtil.methodToProperty(methodName);
return StringUtil.methodToProperty(methodName); });
} }
public static <T> Class<?> getImplClass(LambdaGetter<T> getter) { public static <T> Class<?> getImplClass(LambdaGetter<T> getter) {
SerializedLambda lambda = getSerializedLambda(getter); return MapUtil.computeIfAbsent(implClassMap, getter.getClass(), aClass -> {
return getImplClass(lambda, getter.getClass().getClassLoader()); SerializedLambda lambda = getSerializedLambda(getter);
return getImplClass(lambda, getter.getClass().getClassLoader());
});
} }
@ -69,37 +74,35 @@ public class LambdaUtil {
public static <T> QueryColumn getQueryColumn(LambdaGetter<T> getter) { public static <T> QueryColumn getQueryColumn(LambdaGetter<T> getter) {
ClassLoader classLoader = getter.getClass().getClassLoader(); return MapUtil.computeIfAbsent(queryColumnMap, getter.getClass(), aClass -> {
SerializedLambda lambda = getSerializedLambda(getter); ClassLoader classLoader = getter.getClass().getClassLoader();
Class<?> entityClass = getImplClass(lambda, classLoader); SerializedLambda lambda = getSerializedLambda(getter);
TableInfo tableInfo = TableInfoFactory.ofEntityClass(entityClass); Class<?> entityClass = getImplClass(lambda, classLoader);
String propertyName = getFieldName(getter); TableInfo tableInfo = TableInfoFactory.ofEntityClass(entityClass);
return tableInfo.getQueryColumnByProperty(propertyName); String propertyName = getFieldName(getter);
return tableInfo.getQueryColumnByProperty(propertyName);
});
} }
private static SerializedLambda getSerializedLambda(Serializable getter) { private static SerializedLambda getSerializedLambda(Serializable getter) {
return MapUtil.computeIfAbsent(lambdaMap, getter.getClass(), aClass -> { try {
try { Method method = getter.getClass().getDeclaredMethod("writeReplace");
Method method = getter.getClass().getDeclaredMethod("writeReplace"); method.setAccessible(Boolean.TRUE);
method.setAccessible(Boolean.TRUE); return (SerializedLambda) method.invoke(getter);
return (SerializedLambda) method.invoke(getter); } catch (Exception e) {
} catch (Exception e) { throw new RuntimeException(e);
throw new RuntimeException(e); }
}
});
} }
private static Class<?> getImplClass(SerializedLambda lambda, ClassLoader classLoader) { private static Class<?> getImplClass(SerializedLambda lambda, ClassLoader classLoader) {
String implClass = getImplClassName(lambda); String implClass = getImplClassName(lambda);
return MapUtil.computeIfAbsent(classMap, implClass, s -> { try {
try { return Class.forName(implClass.replace("/", "."), true, classLoader);
return Class.forName(s.replace("/", "."), true, classLoader); } catch (ClassNotFoundException e) {
} catch (ClassNotFoundException e) { throw FlexExceptions.wrap(e);
throw FlexExceptions.wrap(e); }
}
});
} }
private static String getImplClassName(SerializedLambda lambda) { private static String getImplClassName(SerializedLambda lambda) {