From 52f6fe8df098af2a12dbe25c9c5b54095b11fc09 Mon Sep 17 00:00:00 2001 From: liaozan <378024053@qq.com> Date: Sun, 10 Sep 2023 02:16:19 +0800 Subject: [PATCH] Update baseDao methodHandle usage --- .../dao/mybatis/BaseDaoInvocationHandler.java | 76 ++++++++++++++++ .../mybatis/BaseMethodInvocationHandler.java | 67 -------------- .../mybatis/CustomizeMapperFactoryBean.java | 15 ++-- .../mybatis/mapper/BaseMapperStatement.java | 90 +++++++------------ 4 files changed, 111 insertions(+), 137 deletions(-) create mode 100644 support/schbrain-base-dao/src/main/java/com/schbrain/framework/dao/mybatis/BaseDaoInvocationHandler.java delete mode 100644 support/schbrain-base-dao/src/main/java/com/schbrain/framework/dao/mybatis/BaseMethodInvocationHandler.java diff --git a/support/schbrain-base-dao/src/main/java/com/schbrain/framework/dao/mybatis/BaseDaoInvocationHandler.java b/support/schbrain-base-dao/src/main/java/com/schbrain/framework/dao/mybatis/BaseDaoInvocationHandler.java new file mode 100644 index 0000000..04aa2ce --- /dev/null +++ b/support/schbrain-base-dao/src/main/java/com/schbrain/framework/dao/mybatis/BaseDaoInvocationHandler.java @@ -0,0 +1,76 @@ +package com.schbrain.framework.dao.mybatis; + +import com.schbrain.common.exception.BaseException; +import com.schbrain.framework.dao.BaseDao; +import com.schbrain.framework.dao.mybatis.mapper.BaseMapper; +import org.apache.ibatis.reflection.ExceptionUtil; +import org.mybatis.spring.SqlSessionTemplate; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodHandles.Lookup; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author liwu + * @since 2019/7/29 + */ +public class BaseDaoInvocationHandler implements InvocationHandler { + + private final Map methodHandleCache = new ConcurrentHashMap<>(); + + private final T originMapperProxy; + private final BaseMapper baseMapper; + private final Lookup mapperInterfaceLookup; + + public BaseDaoInvocationHandler(T originMapperProxy, SqlSessionTemplate sqlSession, Class mapperInterface) throws IllegalAccessException { + this.originMapperProxy = originMapperProxy; + this.baseMapper = new BaseMapper(sqlSession, mapperInterface); + this.mapperInterfaceLookup = MethodHandles.privateLookupIn(mapperInterface, MethodHandles.lookup()); + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + try { + if (Object.class.equals(method.getDeclaringClass())) { + return method.invoke(this, args); + } else if (method.isDefault()) { + return invokeDefaultMethod(proxy, method, args); + } else if (isBaseMethod(method)) { + return invokeBaseMethod(method, args); + } + } catch (Throwable throwable) { + throw ExceptionUtil.unwrapThrowable(throwable); + } + return method.invoke(originMapperProxy, args); + } + + private Object invokeDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable { + MethodHandle methodHandle = getMethodHandle(proxy, method); + return methodHandle.invokeWithArguments(args); + } + + private MethodHandle getMethodHandle(Object proxy, Method method) { + return methodHandleCache.computeIfAbsent(method, key -> bindHandle(proxy, method)); + } + + private MethodHandle bindHandle(Object proxy, Method method) { + try { + return mapperInterfaceLookup.unreflectSpecial(method, method.getDeclaringClass()).bindTo(proxy); + } catch (IllegalAccessException e) { + throw new BaseException(e.getMessage(), e); + } + } + + private boolean isBaseMethod(Method method) { + return BaseDao.class.equals(method.getDeclaringClass()); + } + + private Object invokeBaseMethod(Method method, Object[] args) { + return baseMapper.invokeBaseMethod(method, args); + } + +} diff --git a/support/schbrain-base-dao/src/main/java/com/schbrain/framework/dao/mybatis/BaseMethodInvocationHandler.java b/support/schbrain-base-dao/src/main/java/com/schbrain/framework/dao/mybatis/BaseMethodInvocationHandler.java deleted file mode 100644 index 37c4fdc..0000000 --- a/support/schbrain-base-dao/src/main/java/com/schbrain/framework/dao/mybatis/BaseMethodInvocationHandler.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.schbrain.framework.dao.mybatis; - -import com.schbrain.framework.dao.BaseDao; -import com.schbrain.framework.dao.mybatis.mapper.BaseMapper; -import org.apache.ibatis.reflection.ExceptionUtil; -import org.mybatis.spring.SqlSessionTemplate; - -import java.io.Serializable; -import java.lang.invoke.MethodHandles.Lookup; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; - -/** - * description - * - * @author liwu on 2019/7/29 - */ -public class BaseMethodInvocationHandler implements InvocationHandler, Serializable { - - private static final long serialVersionUID = -5077848994288044943L; - - private final T originMapperProxy; - - private final BaseMapper baseMapper; - - public BaseMethodInvocationHandler(T originMapperProxy, SqlSessionTemplate sqlSession, Class mapperInterface) { - this.originMapperProxy = originMapperProxy; - baseMapper = new BaseMapper(sqlSession, mapperInterface); - } - - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - try { - if (Object.class.equals(method.getDeclaringClass())) { - return method.invoke(this, args); - } else if (method.isDefault()) { - return invokeDefaultMethod(proxy, method, args); - } else if (isBaseMethod(method)) { - return invokeBaseMethod(method, args); - } - } catch (Throwable t) { - throw ExceptionUtil.unwrapThrowable(t); - } - return method.invoke(originMapperProxy, args); - } - - private Object invokeDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable { - final Constructor constructor = Lookup.class.getDeclaredConstructor(Class.class, int.class); - if (!constructor.isAccessible()) { - constructor.setAccessible(true); - } - final Class declaringClass = method.getDeclaringClass(); - return constructor - .newInstance(declaringClass, Lookup.PRIVATE | Lookup.PROTECTED | Lookup.PACKAGE | Lookup.PUBLIC) - .unreflectSpecial(method, declaringClass).bindTo(proxy).invokeWithArguments(args); - } - - private boolean isBaseMethod(Method method) { - return BaseDao.class.equals(method.getDeclaringClass()); - } - - private Object invokeBaseMethod(Method method, Object[] args) { - return baseMapper.invokeBaseMethod(method, args); - } - -} \ No newline at end of file diff --git a/support/schbrain-base-dao/src/main/java/com/schbrain/framework/dao/mybatis/CustomizeMapperFactoryBean.java b/support/schbrain-base-dao/src/main/java/com/schbrain/framework/dao/mybatis/CustomizeMapperFactoryBean.java index 4632111..c6ed131 100644 --- a/support/schbrain-base-dao/src/main/java/com/schbrain/framework/dao/mybatis/CustomizeMapperFactoryBean.java +++ b/support/schbrain-base-dao/src/main/java/com/schbrain/framework/dao/mybatis/CustomizeMapperFactoryBean.java @@ -1,5 +1,6 @@ package com.schbrain.framework.dao.mybatis; +import cn.hutool.aop.ProxyUtil; import com.github.pagehelper.PageInterceptor; import com.schbrain.framework.dao.BaseDao; import org.apache.ibatis.plugin.Interceptor; @@ -7,7 +8,6 @@ import org.apache.ibatis.session.Configuration; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.mapper.MapperFactoryBean; -import java.lang.reflect.Proxy; import java.util.List; import java.util.Properties; @@ -18,16 +18,11 @@ import java.util.Properties; */ public class CustomizeMapperFactoryBean extends MapperFactoryBean { - public CustomizeMapperFactoryBean() { - super(); - } - public CustomizeMapperFactoryBean(Class mapperInterface) { super(mapperInterface); } @Override - @SuppressWarnings("unchecked") public T getObject() throws Exception { T originMapperProxy = super.getObject(); Class mapperInterface = getMapperInterface(); @@ -38,15 +33,15 @@ public class CustomizeMapperFactoryBean extends MapperFactoryBean { SqlSessionTemplate sqlSession = getSqlSessionTemplate(); Configuration configuration = sqlSession.getConfiguration(); List interceptorList = configuration.getInterceptors(); - boolean hasPageInterceptor = interceptorList.stream().anyMatch(e -> PageInterceptor.class.isAssignableFrom(e.getClass())); + boolean hasPageInterceptor = interceptorList.stream().anyMatch(PageInterceptor.class::isInstance); if (!hasPageInterceptor) { PageInterceptor pageInterceptor = new PageInterceptor(); pageInterceptor.setProperties(new Properties()); configuration.addInterceptor(pageInterceptor); } // 创建代理 - BaseMethodInvocationHandler handler = new BaseMethodInvocationHandler<>(originMapperProxy, sqlSession, mapperInterface); - return (T) Proxy.newProxyInstance(getMapperInterface().getClassLoader(), new Class[]{mapperInterface}, handler); + BaseDaoInvocationHandler handler = new BaseDaoInvocationHandler<>(originMapperProxy, sqlSession, mapperInterface); + return ProxyUtil.newProxyInstance(mapperInterface.getClassLoader(), handler, mapperInterface); } -} \ No newline at end of file +} diff --git a/support/schbrain-base-dao/src/main/java/com/schbrain/framework/dao/mybatis/mapper/BaseMapperStatement.java b/support/schbrain-base-dao/src/main/java/com/schbrain/framework/dao/mybatis/mapper/BaseMapperStatement.java index f7a1c14..bf8dd87 100644 --- a/support/schbrain-base-dao/src/main/java/com/schbrain/framework/dao/mybatis/mapper/BaseMapperStatement.java +++ b/support/schbrain-base-dao/src/main/java/com/schbrain/framework/dao/mybatis/mapper/BaseMapperStatement.java @@ -1,5 +1,6 @@ package com.schbrain.framework.dao.mybatis.mapper; +import cn.hutool.core.util.ArrayUtil; import cn.hutool.crypto.SecureUtil; import com.google.common.base.CaseFormat; import com.google.common.base.Converter; @@ -7,6 +8,7 @@ import com.schbrain.framework.dao.mybatis.mapper.sqlsource.*; import org.apache.ibatis.builder.StaticSqlSource; import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator; import org.apache.ibatis.mapping.*; +import org.apache.ibatis.mapping.MappedStatement.Builder; import org.apache.ibatis.scripting.LanguageDriver; import org.apache.ibatis.session.Configuration; @@ -21,30 +23,22 @@ import java.util.*; */ public class BaseMapperStatement { + private static final Converter CONVERTER = CaseFormat.LOWER_CAMEL.converterTo(CaseFormat.LOWER_UNDERSCORE); private static final String GMT_UPDATE_FIELD = "gmtUpdate"; - private static final String GMT_CREATE_FIELD = "gmtCreate"; - private final Configuration configuration; + private final Map fieldColumnMap = new LinkedHashMap<>(); + private final List objectResultMapList = new ArrayList<>(1); + private final List intResultMapList = new ArrayList<>(1); + private final Configuration configuration; private final Class mapperInterface; - private final LanguageDriver languageDriver; - - private final Map fieldColumnMap = new LinkedHashMap<>(); - private final String tableName; - private final Class domainClass; - private final Field[] fields; - private final List objectResultMapList = new ArrayList<>(1); - - private final List intResultMapList = new ArrayList<>(1); - private String selectClause; - private String insertClause; public BaseMapperStatement(Configuration configuration, Class mapperInterface, Class domainClass, String tableName, Field[] fields) { @@ -74,8 +68,7 @@ public class BaseMapperStatement { } public String getAddMSId() { - String methodName = "add"; - return mapperInterface.getName() + "." + methodName; + return mapperInterface.getName() + ".add"; } public String getAddListMSId(String... fields) { @@ -88,72 +81,58 @@ public class BaseMapperStatement { } public String getGetByIdMSId() { - String methodName = "getById"; - return mapperInterface.getName() + "." + methodName; + return mapperInterface.getName() + ".getById"; } public String getListByIdListMSId() { - String methodName = "getByIdList"; - return mapperInterface.getName() + "." + methodName; + return mapperInterface.getName() + ".getByIdList"; } public String getListByConditionMSId() { - String methodName = "listByCondition"; - return mapperInterface.getName() + "." + methodName; + return mapperInterface.getName() + ".listByCondition"; } public String getListByObjectMSId() { - String methodName = "listByObject"; - return mapperInterface.getName() + "." + methodName; + return mapperInterface.getName() + ".listByObject"; } public String getGetOneByObjectMSId() { - String methodName = "getOneByObject"; - return mapperInterface.getName() + "." + methodName; + return mapperInterface.getName() + ".getOneByObject"; } public String getCountByConditionMSId() { - String methodName = "getCountByCondition"; - return mapperInterface.getName() + "." + methodName; + return mapperInterface.getName() + ".getCountByCondition"; } public String getDeleteByIdMSId() { - String methodName = "deleteById"; - return mapperInterface.getName() + "." + methodName; + return mapperInterface.getName() + ".deleteById"; } public String getDeleteByIdListMSId() { - String methodName = "deleteByIdList"; - return mapperInterface.getName() + "." + methodName; + return mapperInterface.getName() + ".deleteByIdList"; } public String getDeleteByConditionMSId() { - String methodName = "deleteByCondition"; - return mapperInterface.getName() + "." + methodName; + return mapperInterface.getName() + ".deleteByCondition"; } public String getUpdateByIdMSId() { - String methodName = "updateById"; - return mapperInterface.getName() + "." + methodName; + return mapperInterface.getName() + ".updateById"; } public String getUpdateByIdWithNullMSId() { - String methodName = "updateByIdWithNull"; - return mapperInterface.getName() + "." + methodName; + return mapperInterface.getName() + ".updateByIdWithNull"; } public String getUpdateByConditionMSId() { - String methodName = "updateByCondition"; - return mapperInterface.getName() + "." + methodName; + return mapperInterface.getName() + ".updateByCondition"; } public String getUpdateByCompleteSqlMSId() { - String methodName = "updateByCompleteSql"; - return mapperInterface.getName() + "." + methodName; + return mapperInterface.getName() + ".updateByCompleteSql"; } private void setClause() { - Converter converter = CaseFormat.LOWER_CAMEL.converterTo(CaseFormat.LOWER_UNDERSCORE); StringBuilder selectClause = new StringBuilder("select "); StringBuilder insertClause = new StringBuilder("insert into "); insertClause.append(tableName).append("("); @@ -162,7 +141,7 @@ public class BaseMapperStatement { continue; } String fieldName = field.getName(); - String columnName = converter.convert(fieldName); + String columnName = CONVERTER.convert(fieldName); fieldColumnMap.put(fieldName, columnName); selectClause.append(" ").append(columnName).append(","); insertClause.append(" ").append(columnName).append(","); @@ -218,7 +197,7 @@ public class BaseMapperStatement { private String getInsertListScript(String... fields) { String tmpInsertClause; Set fieldSet; - if (null == fields || 0 == fields.length) { + if (ArrayUtil.isEmpty(fields)) { tmpInsertClause = insertClause; fieldSet = fieldColumnMap.keySet(); } else { @@ -277,9 +256,7 @@ public class BaseMapperStatement { ///////////////////listByIdList private void addListByIdListMS() { - String sql = ""; + String sql = ""; SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, List.class); addSelectMappedStatement(getListByIdListMSId(), sqlSource); } @@ -330,9 +307,7 @@ public class BaseMapperStatement { ///////////////////deleteByIdList private void addDeleteByIdListMS() { - String sql = ""; + String sql = ""; SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, List.class); addUpdateMappedStatement(getDeleteByIdListMSId(), sqlSource, SqlCommandType.DELETE); } @@ -408,8 +383,7 @@ public class BaseMapperStatement { if (configuration.hasStatement(msId)) { return; } - MappedStatement ms = new MappedStatement.Builder(configuration, msId, sqlSource, SqlCommandType.SELECT) - .resultMaps(objectResultMapList).flushCacheRequired(true).build(); + MappedStatement ms = new Builder(configuration, msId, sqlSource, SqlCommandType.SELECT).resultMaps(objectResultMapList).flushCacheRequired(true).build(); configuration.addMappedStatement(ms); } @@ -417,8 +391,7 @@ public class BaseMapperStatement { if (configuration.hasStatement(msId)) { return; } - MappedStatement ms = new MappedStatement.Builder(configuration, msId, sqlSource, SqlCommandType.SELECT) - .resultMaps(intResultMapList).build(); + MappedStatement ms = new Builder(configuration, msId, sqlSource, SqlCommandType.SELECT).resultMaps(intResultMapList).build(); configuration.addMappedStatement(ms); } @@ -428,14 +401,11 @@ public class BaseMapperStatement { } MappedStatement ms; if (SqlCommandType.INSERT == sqlCommandType) { - ms = new MappedStatement.Builder(configuration, msId, sqlSource, sqlCommandType) - .resultMaps(intResultMapList).keyGenerator(Jdbc3KeyGenerator.INSTANCE) - .keyColumn("id").keyProperty("id").build(); + ms = new Builder(configuration, msId, sqlSource, sqlCommandType).resultMaps(intResultMapList).keyGenerator(Jdbc3KeyGenerator.INSTANCE).keyColumn("id").keyProperty("id").build(); } else { - ms = new MappedStatement.Builder(configuration, msId, sqlSource, sqlCommandType) - .resultMaps(intResultMapList).build(); + ms = new Builder(configuration, msId, sqlSource, sqlCommandType).resultMaps(intResultMapList).build(); } configuration.addMappedStatement(ms); } -} \ No newline at end of file +} -- GitLab