可自定义SFunction也可以使用MyBatis提供的SFunction
自定义:
/**
* SFunction代替Function,获取序列化能力
*/
@FunctionalInterface
public interface SFunction<T, R> extends Function<T, R>, Serializable {
}
或者导包:
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
方法直接粘就可以用
private static <T, R> Field getField(SFunction<T, R> function) {
Method writeReplaceMethod;
try {
writeReplaceMethod = function.getClass().getDeclaredMethod("writeReplace");
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
// 从序列化方法取出序列化的lambda信息
boolean isAccessible = writeReplaceMethod.isAccessible();
writeReplaceMethod.setAccessible(true);
SerializedLambda serializedLambda;
try {
serializedLambda = (SerializedLambda) writeReplaceMethod.invoke(function);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
writeReplaceMethod.setAccessible(isAccessible);
// 从lambda信息取出method、field、class等
String implMethodName = serializedLambda.getImplMethodName();
// 确保方法是符合规范的get方法,boolean类型是is开头
if (!implMethodName.startsWith("is") && !implMethodName.startsWith("get")) {
throw new RuntimeException("get方法名称: " + implMethodName + ", 不符合java bean规范");
}
// get方法开头为 is 或者 get,将方法名 去除is或者get,然后首字母小写,就是属性名
int prefixLen = implMethodName.startsWith("is") ? 2 : 3;
String fieldName = implMethodName.substring(prefixLen);
String firstChar = fieldName.substring(0, 1);
fieldName = fieldName.replaceFirst(firstChar, firstChar.toLowerCase());
Field field;
try {
field = Class.forName(serializedLambda.getImplClass().replace("/", ".")).getDeclaredField(fieldName);
} catch (ClassNotFoundException | NoSuchFieldException e) {
throw new RuntimeException(e);
}
return field;
}