第一步. 获取SerializedLambda
/**
* 通过反序列化转换 lambda 表达式,该方法只能序列化 lambda 表达式,不能序列化接口实现或者正常非 lambda 写法的对象
*
* @param lambda lambda对象
* @return 返回解析后的 SerializedLambda
*/
public static SerializedLambda resolve(SFunction<?, ?> lambda) {
if (!lambda.getClass().isSynthetic()) {
throw ExceptionUtils.mpe("该方法仅能传入 lambda 表达式产生的合成类");
}
try (ObjectInputStream objIn = new ObjectInputStream(new ByteArrayInputStream(SerializationUtils.serialize(lambda))) {
@Override
protected Class<?> resolveClass(ObjectStreamClass objectStreamClass) throws IOException, ClassNotFoundException {
Class<?> clazz = super.resolveClass(objectStreamClass);
return clazz == java.lang.invoke.SerializedLambda.class ? SerializedLambda.class : clazz;
}
}) {
//读取对象
return (SerializedLambda) objIn.readObject();
} catch (ClassNotFoundException | IOException e) {
throw ExceptionUtils.mpe("This is impossible to happen", e);
}
}
第二步.转换成SerializedLambda
/**
* 解析 lambda 表达式, 该方法只是调用了 {@link SerializedLambda#resolve(SFunction)} 中的方法,在此基础上加了缓存。
* 该缓存可能会在任意不定的时间被清除
*
* @param func 需要解析的 lambda 对象
* @param <T> 类型,被调用的 Function 对象的目标类型
* @return 返回解析后的结果
* @see SerializedLambda#resolve(SFunction)
*/
public static <T> SerializedLambda resolve(SFunction<T, ?> func) {
Class<?> clazz = func.getClass();
return Optional.ofNullable(FUNC_CACHE.get(clazz))
//查看是否在缓存中
.map(WeakReference::get)
.orElseGet(() -> {
// 调用Lambda转换方法转换成 Lambda 序列化对象
SerializedLambda lambda = SerializedLambda.resolve(func);
// 保存到缓存
FUNC_CACHE.put(clazz, new WeakReference<>(lambda));
return lambda;
});
}
第三步.获取字段名称
/**
* 获取 SerializedLambda 对应的列信息,从 lambda 表达式中推测实体类
* <p>
* 如果获取不到列信息,那么本次条件组装将会失败
*
* @param lambda lambda 表达式
* @param onlyColumn 如果是,结果: "name", 如果否: "name" as "name"
* @return 列
* @throws com.baomidou.mybatisplus.core.exceptions.MybatisPlusException 获取不到列信息时抛出异常
* @see SerializedLambda#getImplClass()
* @see SerializedLambda#getImplMethodName()
*/
private String getColumn(SerializedLambda lambda, boolean onlyColumn) throws MybatisPlusException {
//获取方法名称并转换成字段名
String fieldName = PropertyNamer.methodToProperty(lambda.getImplMethodName());
// mp进行一些操作, 不予深究, 最后返回字段名称
Class<?> aClass = lambda.getInstantiatedType();
if (!initColumnMap) {
columnMap = LambdaUtils.getColumnMap(aClass);
}
Assert.notNull(columnMap, "can not find lambda cache for this entity [%s]", aClass.getName());
ColumnCache columnCache = columnMap.get(LambdaUtils.formatKey(fieldName));
Assert.notNull(columnCache, "can not find lambda cache for this property [%s] of entity [%s]",
fieldName, aClass.getName());
return onlyColumn ? columnCache.getColumn() : columnCache.getColumnSelect();
}
来源:oschina
链接:https://my.oschina.net/u/2555967/blog/3162093