cn.cliveyuan.robin.base.util.LambdaUtils Maven / Gradle / Ivy
/*
* Copyright (c) 2020 Clive Yuan ([email protected]).
*/
package cn.cliveyuan.robin.base.util;
import cn.cliveyuan.robin.base.annotation.TableField;
import cn.cliveyuan.robin.base.support.SFunction;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
/**
* Lambda工具
*
* @author Clive Yuan
* @date 2020/10/29
*/
public class LambdaUtils {
/**
* SerializedLambda 反序列化缓存
*/
private static final Map FUNC_CACHE = new ConcurrentHashMap<>();
public static String getFieldName(SFunction func) {
SerializedLambda serializedLambda = resolveSerializedLambdaCache(func);
String getter = serializedLambda.getImplMethodName();
return getColumnName(serializedLambda.getImplClass(), resolveFieldName(getter));
}
/**
* 通过对象字段名获取表字段
*
* @param implClassString 对象
* @param fieldName 字段名
* @return
*/
private static String getColumnName(String implClassString, String fieldName) {
try {
Class> implClass = Class.forName(implClassString.replace('/', '.'));
Field field = implClass.getDeclaredField(fieldName);
TableField tableField = field.getAnnotation(TableField.class);
if (Objects.nonNull(tableField) && RobinStrUtils.isNotBlank(tableField.value())) {
return tableField.value();
}
} catch (ClassNotFoundException | NoSuchFieldException e) {
throw new RuntimeException(e);
}
return fieldName;
}
private static SerializedLambda resolveSerializedLambdaCache(SFunction func) {
Class> clazz = func.getClass();
String name = clazz.getName();
return Optional.ofNullable(FUNC_CACHE.get(name))
.orElseGet(() -> {
SerializedLambda lambda = resolveSerializedLambda(func);
FUNC_CACHE.put(name, lambda);
return lambda;
});
}
private static SerializedLambda resolveSerializedLambda(SFunction func) {
try {
// 通过获取对象方法,判断是否存在该方法
Method method = func.getClass().getDeclaredMethod("writeReplace");
method.setAccessible(Boolean.TRUE);
// 利用jdk的SerializedLambda 解析方法引用
return (SerializedLambda) method.invoke(func);
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}
private static String resolveFieldName(String getMethodName) {
if (getMethodName.startsWith("get")) {
getMethodName = getMethodName.substring(3);
} else if (getMethodName.startsWith("is")) {
getMethodName = getMethodName.substring(2);
}
// 小写第一个字母
return SqlUtils.firstToLowerCase(getMethodName);
}
}