Przeglądaj źródła

refactor: 重构 lambda 信息提取

hcl 4 lat temu
rodzic
commit
d413555685

+ 3 - 3
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/conditions/AbstractLambdaWrapper.java

@@ -19,10 +19,10 @@ import com.baomidou.mybatisplus.core.toolkit.Assert;
 import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
 import com.baomidou.mybatisplus.core.toolkit.StringPool;
 import com.baomidou.mybatisplus.core.toolkit.support.ColumnCache;
+import com.baomidou.mybatisplus.core.toolkit.support.LambdaMeta;
 import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
 import org.apache.ibatis.reflection.property.PropertyNamer;
 
-import java.lang.invoke.SerializedLambda;
 import java.util.Arrays;
 import java.util.Map;
 
@@ -72,9 +72,9 @@ public abstract class AbstractLambdaWrapper<T, Children extends AbstractLambdaWr
      * @throws com.baomidou.mybatisplus.core.exceptions.MybatisPlusException 获取不到列信息时抛出异常
      */
     protected ColumnCache getColumnCache(SFunction<T, ?> column) {
-        SerializedLambda lambda = LambdaUtils.extract(column);
+        LambdaMeta lambda = LambdaUtils.extract(column);
         String fileName = PropertyNamer.methodToProperty(lambda.getImplMethodName());
-        return getColumnCache(fileName, LambdaUtils.instantiatedClass(lambda));
+        return getColumnCache(fileName, lambda.getInstantiatedClass());
     }
 
     private void tryInitCache(Class<?> lambdaClass) {

+ 4 - 39
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/toolkit/LambdaUtils.java

@@ -19,10 +19,11 @@ import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
 import com.baomidou.mybatisplus.core.metadata.TableInfo;
 import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
 import com.baomidou.mybatisplus.core.toolkit.support.ColumnCache;
+import com.baomidou.mybatisplus.core.toolkit.support.LambdaMeta;
 import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
+import com.baomidou.mybatisplus.core.toolkit.support.SerializedLambdaMeta;
 
 import java.lang.invoke.SerializedLambda;
-import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.Map;
@@ -37,16 +38,6 @@ import static java.util.Locale.ENGLISH;
  * @since 2018-05-10
  */
 public final class LambdaUtils {
-    private static final Field FIELD_CAPTURING_CLASS;
-
-    static {
-        try {
-            Class<SerializedLambda> aClass = SerializedLambda.class;
-            FIELD_CAPTURING_CLASS = ReflectionKit.setAccessible(aClass.getDeclaredField("capturingClass"));
-        } catch (NoSuchFieldException e) {
-            throw new MybatisPlusException(e);
-        }
-    }
 
     /**
      * 字段映射
@@ -60,10 +51,10 @@ public final class LambdaUtils {
      * @param <T>  类型,被调用的 Function 对象的目标类型
      * @return 返回解析后的结果
      */
-    public static <T> SerializedLambda extract(SFunction<T, ?> func) {
+    public static <T> LambdaMeta extract(SFunction<T, ?> func) {
         try {
             Method method = func.getClass().getDeclaredMethod("writeReplace");
-            return (SerializedLambda) ReflectionKit.setAccessible(method).invoke(func);
+            return new SerializedLambdaMeta((SerializedLambda) ReflectionKit.setAccessible(method).invoke(func));
         } catch (NoSuchMethodException e) {
             String message = "Cannot find method writeReplace, please make sure that the lambda composite class is currently passed in";
             throw new MybatisPlusException(message);
@@ -72,32 +63,6 @@ public final class LambdaUtils {
         }
     }
 
-    /**
-     * 实例化该接口的类名
-     *
-     * @param lambda lambda 对象
-     * @return 返回对应的实例类
-     */
-    public static Class<?> instantiatedClass(SerializedLambda lambda) {
-        String instantiatedMethodType = lambda.getInstantiatedMethodType();
-        String instantiatedType = instantiatedMethodType.substring(2, instantiatedMethodType.indexOf(';')).replace('/', '.');
-        return ClassUtils.toClassConfident(instantiatedType, capturingClass(lambda).getClassLoader());
-    }
-
-    /**
-     * 获取 lambda 的捕获类,这取决于 lambda 类在构造时所处的类
-     *
-     * @param lambda lambda
-     * @return 返回对应的捕获类
-     */
-    public static Class<?> capturingClass(SerializedLambda lambda) {
-        try {
-            return (Class<?>) FIELD_CAPTURING_CLASS.get(lambda);
-        } catch (IllegalAccessException e) {
-            throw new MybatisPlusException(e);
-        }
-    }
-
     /**
      * 格式化 key 将传入的 key 变更为大写格式
      *

+ 12 - 0
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/toolkit/support/LambdaMeta.java

@@ -0,0 +1,12 @@
+package com.baomidou.mybatisplus.core.toolkit.support;
+
+/**
+ * Created by hcl at 2021/5/14
+ */
+public interface LambdaMeta {
+
+    String getImplMethodName();
+
+    Class<?> getInstantiatedClass();
+
+}

+ 51 - 0
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/toolkit/support/SerializedLambdaMeta.java

@@ -0,0 +1,51 @@
+package com.baomidou.mybatisplus.core.toolkit.support;
+
+import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
+import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
+import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
+
+import java.lang.invoke.SerializedLambda;
+import java.lang.reflect.Field;
+
+/**
+ * Created by hcl at 2021/5/14
+ */
+public class SerializedLambdaMeta implements LambdaMeta {
+    private static final Field FIELD_CAPTURING_CLASS;
+
+    static {
+        try {
+            Class<SerializedLambda> aClass = SerializedLambda.class;
+            FIELD_CAPTURING_CLASS = ReflectionKit.setAccessible(aClass.getDeclaredField("capturingClass"));
+        } catch (NoSuchFieldException e) {
+            throw new MybatisPlusException(e);
+        }
+    }
+
+    private final SerializedLambda lambda;
+
+    public SerializedLambdaMeta(SerializedLambda lambda) {
+        this.lambda = lambda;
+    }
+
+    @Override
+    public String getImplMethodName() {
+        return lambda.getImplMethodName();
+    }
+
+    @Override
+    public Class<?> getInstantiatedClass() {
+        String instantiatedMethodType = lambda.getInstantiatedMethodType();
+        String instantiatedType = instantiatedMethodType.substring(2, instantiatedMethodType.indexOf(';')).replace('/', '.');
+        return ClassUtils.toClassConfident(instantiatedType, getCapturingClass().getClassLoader());
+    }
+
+    public Class<?> getCapturingClass() {
+        try {
+            return (Class<?>) FIELD_CAPTURING_CLASS.get(lambda);
+        } catch (IllegalAccessException e) {
+            throw new MybatisPlusException(e);
+        }
+    }
+
+}

+ 6 - 7
mybatis-plus-core/src/test/java/com/baomidou/mybatisplus/test/toolkit/LambdaUtilsTest.java

@@ -16,12 +16,11 @@
 package com.baomidou.mybatisplus.test.toolkit;
 
 import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
+import com.baomidou.mybatisplus.core.toolkit.support.LambdaMeta;
 import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
 import lombok.Getter;
 import org.junit.jupiter.api.Test;
 
-import java.lang.invoke.SerializedLambda;
-
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertSame;
 
@@ -35,10 +34,10 @@ class LambdaUtilsTest {
      */
     @Test
     void testExtract() {
-        SFunction<TestModel, Object> getId = TestModel::getId;
-        SerializedLambda lambda = LambdaUtils.extract(getId);
-        assertNotNull(lambda);
-        assertSame(TestModel.class, LambdaUtils.instantiatedClass(lambda));
+        SFunction<TestModel, Object> function = TestModel::getName;
+        LambdaMeta meta = LambdaUtils.extract(function);
+        assertNotNull(meta);
+        assertSame(TestModel.class, meta.getInstantiatedClass());
     }
 
     /**
@@ -57,7 +56,7 @@ class LambdaUtilsTest {
     // 处理 ISSUE:https://gitee.com/baomidou/mybatis-plus/issues/I13Y8Y,由于 java 本身处理的问题,这里无法获取到实例
     private abstract static class BaseHolder<T extends Named> {
 
-        SerializedLambda toLambda() {
+        LambdaMeta toLambda() {
             return LambdaUtils.extract(T::getName);
         }