Ver Fonte

调整SPI实现(新增getProxyTargetObject()方法获取真实代理).

https://github.com/baomidou/mybatis-plus/issues/6769
nieqiurong há 3 meses atrás
pai
commit
ebe329ac2f

+ 79 - 0
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/spi/CompatibleHelper.java

@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2011-2025, baomidou (jobob@qq.com).
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.baomidou.mybatisplus.core.spi;
+
+import com.baomidou.mybatisplus.core.toolkit.Assert;
+import org.apache.ibatis.logging.Log;
+import org.apache.ibatis.logging.LogFactory;
+
+import java.util.ServiceLoader;
+
+/**
+ * 兼容处理辅助类
+ * <p>默认加载使用SPI实现,需要手动指定请使用{@link #setCompatibleSet(CompatibleSet)}</p>
+ */
+public class CompatibleHelper {
+
+    private static final Log LOG = LogFactory.getLog(CompatibleHelper.class);
+
+    private static CompatibleSet COMPATIBLE_SET = null;
+
+    static {
+        ServiceLoader<CompatibleSet> loader = ServiceLoader.load(CompatibleSet.class, CompatibleSet.class.getClassLoader());
+        int size = 0;
+        for (CompatibleSet compatibleSet : loader) {
+            size++;
+            LOG.debug("Load compatibleSet: " + compatibleSet);
+            COMPATIBLE_SET = compatibleSet;
+        }
+        if (size > 1) {
+            LOG.warn("There are currently multiple implementations, and the last one is used " + COMPATIBLE_SET);
+        }
+    }
+
+    /**
+     * 判断是否存在 {@link com.baomidou.mybatisplus.core.spi.CompatibleSet} 实例
+     *
+     * @return 是否存在 (存在返回true,为空返回false)
+     * @since 3.5.12
+     */
+    public static boolean hasCompatibleSet() {
+        return COMPATIBLE_SET != null;
+    }
+
+    /**
+     * 手动指定 {@link com.baomidou.mybatisplus.core.spi.CompatibleSet} 实例
+     *
+     * @param compatibleSet {@link com.baomidou.mybatisplus.core.spi.CompatibleSet} 实例
+     * @since 3.5.12
+     */
+    public static void setCompatibleSet(CompatibleSet compatibleSet) {
+        COMPATIBLE_SET = compatibleSet;
+    }
+
+    /**
+     * 获取{@link com.baomidou.mybatisplus.core.spi.CompatibleSet}实例
+     * <p>当为空时会抛出异常,需要检查是否为空请使用{@link #hasCompatibleSet()}</p>
+     *
+     * @return {@link com.baomidou.mybatisplus.core.spi.CompatibleSet}
+     * @see #setCompatibleSet(CompatibleSet)
+     */
+    public static CompatibleSet getCompatibleSet() {
+        Assert.isTrue(hasCompatibleSet(), "Please add specific implementation dependencies or use the setCompatibleSet method to specify");
+        return COMPATIBLE_SET;
+    }
+
+}

+ 63 - 0
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/spi/CompatibleSet.java

@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2011-2025, baomidou (jobob@qq.com).
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.baomidou.mybatisplus.core.spi;
+
+import org.apache.ibatis.logging.Log;
+import org.apache.ibatis.session.SqlSession;
+import org.apache.ibatis.session.SqlSessionFactory;
+
+import java.io.InputStream;
+import java.util.function.Consumer;
+
+/**
+ * Web 开发平台待兼容方法集接口类
+ */
+public interface CompatibleSet {
+
+    SqlSession getSqlSession(SqlSessionFactory sessionFactory);
+
+    void closeSqlSession(SqlSession session, SqlSessionFactory sessionFactory);
+
+    boolean executeBatch(SqlSessionFactory sqlSessionFactory, Log log, Consumer<SqlSession> consumer);
+
+    /**
+     * @deprecated 3.5.12 无需实现
+     */
+    @Deprecated
+    InputStream getInputStream(String path) throws Exception;
+
+    /**
+     * 获取容器bean实例
+     *
+     * @param clz 类型
+     * @return bean实例 (当无实例时返回null)
+     * @since 3.5.12
+     */
+    default <T> T getBean(Class<T> clz) {
+        return null;
+    }
+
+    /**
+     * 获取真实被代理的对象 (如果没有被代理,请返回原始对象)
+     *
+     * @param mapper Mapper对象
+     * @return 真实对象
+     */
+    default Object getProxyTargetObject(Object mapper) {
+        return null;
+    }
+
+}

+ 6 - 19
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/toolkit/MybatisUtils.java

@@ -20,6 +20,7 @@ import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
 import com.baomidou.mybatisplus.core.handlers.IJsonTypeHandler;
 import com.baomidou.mybatisplus.core.metadata.MapperProxyMetadata;
 import com.baomidou.mybatisplus.core.override.MybatisMapperProxy;
+import com.baomidou.mybatisplus.core.spi.CompatibleHelper;
 import lombok.experimental.UtilityClass;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.ibatis.reflection.MetaObject;
@@ -30,7 +31,6 @@ import org.apache.ibatis.session.SqlSessionFactory;
 import org.apache.ibatis.session.defaults.DefaultSqlSession;
 import org.apache.ibatis.type.TypeException;
 import org.apache.ibatis.type.TypeHandler;
-import org.springframework.aop.framework.AopProxyUtils;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Proxy;
@@ -119,21 +119,7 @@ public class MybatisUtils {
      * @since 3.5.7
      */
     public static MybatisMapperProxy<?> getMybatisMapperProxy(Object mapper) {
-        if (mapper instanceof MybatisMapperProxy) {
-            // fast return
-            return (MybatisMapperProxy<?>) mapper;
-        }
-        Object result = mapper;
-        if (AopUtils.isLoadSpringAop()) {
-            while (org.springframework.aop.support.AopUtils.isAopProxy(result)) {
-                result = AopProxyUtils.getSingletonTarget(result);
-            }
-        }
-        if (result != null) {
-            while (Proxy.isProxyClass(result.getClass())) {
-                result = Proxy.getInvocationHandler(result);
-            }
-        }
+        Object result = extractMapperProxy(mapper);
         if (result instanceof MybatisMapperProxy) {
             return (MybatisMapperProxy<?>) result;
         }
@@ -153,9 +139,10 @@ public class MybatisUtils {
             return mapper;
         }
         Object result = mapper;
-        if (AopUtils.isLoadSpringAop()) {
-            while (org.springframework.aop.support.AopUtils.isAopProxy(result)) {
-                result = AopProxyUtils.getSingletonTarget(result);
+        if (CompatibleHelper.hasCompatibleSet()) {
+            Object proxyTargetObject = CompatibleHelper.getCompatibleSet().getProxyTargetObject(result);
+            if (proxyTargetObject != null) {
+                result = proxyTargetObject;
             }
         }
         if (result != null) {

+ 1 - 1
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/activerecord/AbstractModel.java

@@ -21,7 +21,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.TableInfo;
 import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
 import com.baomidou.mybatisplus.core.toolkit.*;
-import com.baomidou.mybatisplus.extension.spi.CompatibleHelper;
+import com.baomidou.mybatisplus.core.spi.CompatibleHelper;
 import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
 import org.apache.ibatis.logging.LogFactory;
 import org.apache.ibatis.session.SqlSession;

+ 4 - 0
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/spi/CompatibleHelper.java

@@ -24,7 +24,11 @@ import java.util.ServiceLoader;
 /**
  * 兼容处理辅助类
  * <p>默认加载使用SPI实现,需要手动指定请使用{@link #setCompatibleSet(CompatibleSet)}</p>
+ *
+ * @see com.baomidou.mybatisplus.core.spi.CompatibleHelper
+ * @deprecated 3.5.12
  */
+@Deprecated
 public class CompatibleHelper {
 
     private static final Log LOG = LogFactory.getLog(CompatibleHelper.class);

+ 5 - 31
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/spi/CompatibleSet.java

@@ -15,39 +15,13 @@
  */
 package com.baomidou.mybatisplus.extension.spi;
 
-import org.apache.ibatis.logging.Log;
-import org.apache.ibatis.session.SqlSession;
-import org.apache.ibatis.session.SqlSessionFactory;
-
-import java.io.InputStream;
-import java.util.function.Consumer;
-
 /**
  * Web 开发平台待兼容方法集接口类
+ *
+ * @see com.baomidou.mybatisplus.core.spi.CompatibleSet
+ * @deprecated 3.5.12
  */
-public interface CompatibleSet {
-
-    SqlSession getSqlSession(SqlSessionFactory sessionFactory);
-
-    void closeSqlSession(SqlSession session, SqlSessionFactory sessionFactory);
-
-    boolean executeBatch(SqlSessionFactory sqlSessionFactory, Log log, Consumer<SqlSession> consumer);
-
-    /**
-     * @deprecated 3.5.12 无需实现
-     */
-    @Deprecated
-    InputStream getInputStream(String path) throws Exception;
-
-    /**
-     * 获取容器bean实例
-     *
-     * @param clz 类型
-     * @return bean实例 (当无实例时返回null)
-     * @since 3.5.12
-     */
-    default <T> T getBean(Class<T> clz) {
-        return null;
-    }
+@Deprecated
+public interface CompatibleSet extends com.baomidou.mybatisplus.core.spi.CompatibleSet {
 
 }

+ 2 - 2
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/toolkit/SqlHelper.java

@@ -21,8 +21,8 @@ import com.baomidou.mybatisplus.core.metadata.TableInfo;
 import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
 import com.baomidou.mybatisplus.core.toolkit.*;
 import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
-import com.baomidou.mybatisplus.extension.spi.CompatibleHelper;
-import com.baomidou.mybatisplus.extension.spi.CompatibleSet;
+import com.baomidou.mybatisplus.core.spi.CompatibleHelper;
+import com.baomidou.mybatisplus.core.spi.CompatibleSet;
 import org.apache.ibatis.executor.BatchResult;
 import org.apache.ibatis.logging.Log;
 import org.apache.ibatis.session.ExecutorType;

+ 13 - 0
mybatis-plus-spring/src/main/java/com/baomidou/mybatisplus/extension/spi/SpringCompatibleSet.java

@@ -15,6 +15,7 @@
  */
 package com.baomidou.mybatisplus.extension.spi;
 
+import com.baomidou.mybatisplus.core.toolkit.AopUtils;
 import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
 import com.baomidou.mybatisplus.extension.spring.MybatisPlusApplicationContextAware;
 import lombok.SneakyThrows;
@@ -28,6 +29,7 @@ import org.apache.ibatis.session.SqlSessionFactory;
 import org.mybatis.spring.MyBatisExceptionTranslator;
 import org.mybatis.spring.SqlSessionHolder;
 import org.mybatis.spring.SqlSessionUtils;
+import org.springframework.aop.framework.AopProxyUtils;
 import org.springframework.beans.factory.ObjectProvider;
 import org.springframework.context.ApplicationContext;
 import org.springframework.core.io.ClassPathResource;
@@ -106,4 +108,15 @@ public class SpringCompatibleSet implements CompatibleSet {
         return null;
     }
 
+    @Override
+    public Object getProxyTargetObject(Object mapper) {
+        Object result = mapper;
+        if (AopUtils.isLoadSpringAop()) {
+            while (org.springframework.aop.support.AopUtils.isAopProxy(result)) {
+                result = AopProxyUtils.getSingletonTarget(result);
+            }
+        }
+        return result;
+    }
+
 }

+ 1 - 0
mybatis-plus-spring/src/main/resources/META-INF/services/com.baomidou.mybatisplus.core.spi.CompatibleSet

@@ -0,0 +1 @@
+com.baomidou.mybatisplus.extension.spi.SpringCompatibleSet