mybatis-plus LambdaQueryWrapper类的实现原理

jdk8 lambda 是实现原理

  1. 定义一个函数式接口Func
@FunctionalInterface
interface Func extends Serializable {
    String func(Object obj);
}
  1. 编写一段代码
Func func=Object::toString;

等价于,但上面最终可以获取toString方法名,下面只能获取到编译器生成的方法名

Func func=o->o.toString()
  1. 运行代码,jvm加上-Djdk.internal.lambda.dumpProxyClasses=(Path),可以看java.lang.invoke.InnerClassLambdaMetafactory类
public class MailMicroServiceApplication {
    public static void main(String[] args) {
        Func func=Object::toString;
        func.func(new Object());
    }
}

4.运行完成后会生成
在这里插入图片描述
5.idea 工具反编译后

package top.hunfan.mail;

import java.lang.invoke.SerializedLambda;
import java.lang.invoke.LambdaForm.Hidden;

// $FF: synthetic class
final class MailMicroServiceApplication$$Lambda$85 implements Func {
    private MailMicroServiceApplication$$Lambda$85() {
    }

    @Hidden
    public String func(Object var1) {
        return var1.toString();
    }

    private final Object writeReplace() {
        return new SerializedLambda(MailMicroServiceApplication.class, "top/hunfan/mail/Func", "func", "(Ljava/lang/Object;)Ljava/lang/String;", 5, "java/lang/Object", "toString", "()Ljava/lang/String;", "(Ljava/lang/Object;)Ljava/lang/String;", new Object[0]);
    }
}

继承Serializable接口,lambda合成的类多出writeReplace方法,返回java.lang.invoke.SerializedLambda类,
该类的serializedLambda.getImplMethodName()方法可以返回方法名称

mybatis-plus的 LambdaQueryWrapper类实现

  1. LambdaQueryWrapper抽象类AbstractLambdaWrapper有一个方法
 protected String columnToString(SFunction<T, ?> column, boolean onlyColumn) {
        return getColumn(LambdaUtils.resolve(column), onlyColumn);
    }
 private String getColumn(SerializedLambda lambda, boolean onlyColumn) throws MybatisPlusException {
        String fieldName = PropertyNamer.methodToProperty(lambda.getImplMethodName());
        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();
    }

原理也是借用jdk函数式接口实现Serializable接口后,序列化变成SerializedLambda类可以获取实现调用的方法
结论:

Func func=Object::toString;

Func函数接口有实现序列化接口,序列化后的SerializedLambda,调用getImplMethodName()方法可以得到“toString”

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值