From d53ccd0857b2b0a7a91b01ff90fbd9ee2334ce5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=8B=E8=BE=9E=E6=9C=AA=E5=AF=92?= <545073804@qq.com> Date: Fri, 25 Jul 2025 02:15:29 +0800 Subject: [PATCH 1/3] =?UTF-8?q?update=20=E6=8A=8A=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=9D=83=E9=99=90=E6=B3=A8=E8=A7=A3=E5=85=A8=E9=83=A8=E4=BA=A4?= =?UTF-8?q?=E7=BB=99AOP=E5=A4=84=E7=90=86=EF=BC=8C=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E5=90=AF=E5=8A=A8=E6=97=B6=E4=B8=8D=E5=86=8D=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E5=A4=9A=E4=BD=99=E7=9A=84Mapper=E6=89=AB=E6=8F=8F=E6=93=8D?= =?UTF-8?q?=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mybatis/aspect/DataPermissionAspect.java | 20 +++- .../mybatis/config/MybatisPlusConfig.java | 2 +- .../handler/PlusDataPermissionHandler.java | 108 +----------------- .../PlusDataPermissionInterceptor.java | 27 ++--- 4 files changed, 35 insertions(+), 122 deletions(-) diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/aspect/DataPermissionAspect.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/aspect/DataPermissionAspect.java index 1c83cc392..20b8c1e49 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/aspect/DataPermissionAspect.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/aspect/DataPermissionAspect.java @@ -6,8 +6,10 @@ import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.reflect.MethodSignature; import org.dromara.common.mybatis.annotation.DataPermission; import org.dromara.common.mybatis.helper.DataPermissionHelper; +import org.springframework.core.annotation.AnnotationUtils; /** * 数据权限处理 @@ -21,8 +23,22 @@ public class DataPermissionAspect { /** * 处理请求前执行 */ - @Before(value = "@annotation(dataPermission)") - public void doBefore(JoinPoint joinPoint, DataPermission dataPermission) { + @Before(value = "@annotation(org.dromara.common.mybatis.annotation.DataPermission) || @within(org.dromara.common.mybatis.annotation.DataPermission)") + public void doBefore(JoinPoint joinPoint) { + DataPermission dataPermission = null; + // 优先获取方法上的注解 + if (joinPoint.getSignature() instanceof MethodSignature signature) { + dataPermission = AnnotationUtils.findAnnotation(signature.getMethod(), DataPermission.class); +// log.info("数据权限处理器拦截方法: {}\t方法是否具有数据权限注解:{}", signature.getMethod().getName(),dataPermission != null); + } + + // 如果方法上不存在,则获取类上的注解 + if (dataPermission == null) { + dataPermission = AnnotationUtils.findAnnotation(joinPoint.getTarget().getClass(), DataPermission.class); +// log.info("数据权限处理器拦截类: {}\t类是否具有数据权限注解:{}", joinPoint.getTarget().getClass().getCanonicalName(),dataPermission != null); + } +// log.info("数据权限注解:{}",dataPermission); + // 因为处理条件是 @annotation(DataPermission) || @within(DataPermission) ,所以方法上的注解或者类上的注解必然会一个不为空,否则不会进入到此代理方法 DataPermissionHelper.setPermission(dataPermission); } diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/config/MybatisPlusConfig.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/config/MybatisPlusConfig.java index 00c26912e..51bec5a99 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/config/MybatisPlusConfig.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/config/MybatisPlusConfig.java @@ -54,7 +54,7 @@ public class MybatisPlusConfig { * 数据权限拦截器 */ public PlusDataPermissionInterceptor dataPermissionInterceptor() { - return new PlusDataPermissionInterceptor(SpringUtils.getProperty("mybatis-plus.mapperPackage")); + return new PlusDataPermissionInterceptor(); } /** diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java index 6dee1214a..5c2ca983b 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java @@ -1,6 +1,5 @@ package org.dromara.common.mybatis.handler; -import cn.hutool.core.annotation.AnnotationUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import lombok.AllArgsConstructor; @@ -10,7 +9,6 @@ import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.operators.conditional.AndExpression; import net.sf.jsqlparser.expression.operators.relational.ParenthesedExpressionList; import net.sf.jsqlparser.parser.CCJSqlParserUtil; -import org.apache.ibatis.io.Resources; import org.dromara.common.core.domain.dto.RoleDTO; import org.dromara.common.core.domain.model.LoginUser; import org.dromara.common.core.exception.ServiceException; @@ -22,22 +20,13 @@ import org.dromara.common.mybatis.annotation.DataPermission; import org.dromara.common.mybatis.enums.DataScopeType; import org.dromara.common.mybatis.helper.DataPermissionHelper; import org.dromara.common.satoken.utils.LoginHelper; -import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.expression.BeanFactoryResolver; -import org.springframework.core.io.Resource; -import org.springframework.core.io.support.PathMatchingResourcePatternResolver; -import org.springframework.core.io.support.ResourcePatternResolver; -import org.springframework.core.type.ClassMetadata; -import org.springframework.core.type.classreading.CachingMetadataReaderFactory; import org.springframework.expression.*; import org.springframework.expression.common.TemplateParserContext; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; -import org.springframework.util.ClassUtils; -import java.lang.reflect.Method; import java.util.*; -import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; /** @@ -49,11 +38,6 @@ import java.util.function.Function; @Slf4j public class PlusDataPermissionHandler { - /** - * 类名称与注解的映射关系缓存(由于aop无法拦截mybatis接口类上的注解 只能通过启动预扫描的方式进行) - */ - private final Map dataPermissionCacheMap = new ConcurrentHashMap<>(); - /** * spel 解析器 */ @@ -64,27 +48,17 @@ public class PlusDataPermissionHandler { */ private final BeanResolver beanResolver = new BeanFactoryResolver(SpringUtils.getBeanFactory()); - /** - * 构造方法,扫描指定包下的 Mapper 类并初始化缓存 - * - * @param mapperPackage Mapper 类所在的包路径 - */ - public PlusDataPermissionHandler(String mapperPackage) { - scanMapperClasses(mapperPackage); - } - /** * 获取数据过滤条件的 SQL 片段 * * @param where 原始的查询条件表达式 - * @param mappedStatementId Mapper 方法的 ID * @param isSelect 是否为查询语句 * @return 数据过滤条件的 SQL 片段 */ - public Expression getSqlSegment(Expression where, String mappedStatementId, boolean isSelect) { + public Expression getSqlSegment(Expression where, boolean isSelect) { try { // 获取数据权限配置 - DataPermission dataPermission = getDataPermission(mappedStatementId); + DataPermission dataPermission = getDataPermission(); // 获取当前登录用户信息 LoginUser currentUser = DataPermissionHelper.getVariable("user"); if (ObjectUtil.isNull(currentUser)) { @@ -206,92 +180,22 @@ public class PlusDataPermissionHandler { return StringUtils.EMPTY; } - /** - * 扫描指定包下的 Mapper 类,并查找其中带有特定注解的方法或类 - * - * @param mapperPackage Mapper 类所在的包路径 - */ - private void scanMapperClasses(String mapperPackage) { - // 创建资源解析器和元数据读取工厂 - PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); - CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory(); - // 将 Mapper 包路径按分隔符拆分为数组 - String[] packagePatternArray = StringUtils.splitPreserveAllTokens(mapperPackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS); - String classpath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX; - try { - for (String packagePattern : packagePatternArray) { - // 将包路径转换为资源路径 - String path = ClassUtils.convertClassNameToResourcePath(packagePattern); - // 获取指定路径下的所有 .class 文件资源 - Resource[] resources = resolver.getResources(classpath + path + "/*.class"); - for (Resource resource : resources) { - // 获取资源的类元数据 - ClassMetadata classMetadata = factory.getMetadataReader(resource).getClassMetadata(); - // 获取资源对应的类对象 - Class clazz = Resources.classForName(classMetadata.getClassName()); - // 查找类中的特定注解 - findAnnotation(clazz); - } - } - } catch (Exception e) { - log.error("初始化数据安全缓存时出错:{}", e.getMessage()); - } - } - - /** - * 在指定的类中查找特定的注解 DataPermission,并将带有这个注解的方法或类存储到 dataPermissionCacheMap 中 - * - * @param clazz 要查找的类 - */ - private void findAnnotation(Class clazz) { - DataPermission dataPermission; - for (Method method : clazz.getMethods()) { - if (method.isDefault() || method.isVarArgs()) { - continue; - } - String mappedStatementId = clazz.getName() + "." + method.getName(); - if (AnnotationUtil.hasAnnotation(method, DataPermission.class)) { - dataPermission = AnnotationUtil.getAnnotation(method, DataPermission.class); - dataPermissionCacheMap.put(mappedStatementId, dataPermission); - } - } - if (AnnotationUtil.hasAnnotation(clazz, DataPermission.class)) { - dataPermission = AnnotationUtil.getAnnotation(clazz, DataPermission.class); - dataPermissionCacheMap.put(clazz.getName(), dataPermission); - } - } - /** * 根据映射语句 ID 或类名获取对应的 DataPermission 注解对象 * - * @param mapperId 映射语句 ID * @return DataPermission 注解对象,如果不存在则返回 null */ - public DataPermission getDataPermission(String mapperId) { - // 检查上下文中是否包含映射语句 ID 对应的 DataPermission 注解对象 - if (DataPermissionHelper.getPermission() != null) { - return DataPermissionHelper.getPermission(); - } - // 检查缓存中是否包含映射语句 ID 对应的 DataPermission 注解对象 - if (dataPermissionCacheMap.containsKey(mapperId)) { - return dataPermissionCacheMap.get(mapperId); - } - // 如果缓存中不包含映射语句 ID 对应的 DataPermission 注解对象,则尝试使用类名作为键查找 - String clazzName = mapperId.substring(0, mapperId.lastIndexOf(".")); - if (dataPermissionCacheMap.containsKey(clazzName)) { - return dataPermissionCacheMap.get(clazzName); - } - return null; + public DataPermission getDataPermission() { + return DataPermissionHelper.getPermission(); } /** * 检查给定的映射语句 ID 是否有效,即是否能够找到对应的 DataPermission 注解对象 * - * @param mapperId 映射语句 ID * @return 如果找到对应的 DataPermission 注解对象,则返回 false;否则返回 true */ - public boolean invalid(String mapperId) { - return getDataPermission(mapperId) == null; + public boolean invalid() { + return getDataPermission() == null; } /** diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlusDataPermissionInterceptor.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlusDataPermissionInterceptor.java index 85a4d0abc..abd22e9a4 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlusDataPermissionInterceptor.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlusDataPermissionInterceptor.java @@ -35,16 +35,10 @@ import java.util.List; @Slf4j public class PlusDataPermissionInterceptor extends BaseMultiTableInnerInterceptor implements InnerInterceptor { - private final PlusDataPermissionHandler dataPermissionHandler; - /** - * 构造函数,初始化 PlusDataPermissionHandler 实例 - * - * @param mapperPackage 扫描的映射器包 + * 数据权限处理器 */ - public PlusDataPermissionInterceptor(String mapperPackage) { - this.dataPermissionHandler = new PlusDataPermissionHandler(mapperPackage); - } + private final PlusDataPermissionHandler dataPermissionHandler = new PlusDataPermissionHandler(); /** * 在执行查询之前,检查并处理数据权限相关逻辑 @@ -64,7 +58,7 @@ public class PlusDataPermissionInterceptor extends BaseMultiTableInnerIntercepto return; } // 检查是否缺少有效的数据权限注解 - if (dataPermissionHandler.invalid(ms.getId())) { + if (dataPermissionHandler.invalid()) { return; } // 解析 sql 分配对应方法 @@ -92,7 +86,7 @@ public class PlusDataPermissionInterceptor extends BaseMultiTableInnerIntercepto return; } // 检查是否缺少有效的数据权限注解 - if (dataPermissionHandler.invalid(ms.getId())) { + if (dataPermissionHandler.invalid()) { return; } PluginUtils.MPBoundSql mpBs = mpSh.mPBoundSql(); @@ -111,10 +105,10 @@ public class PlusDataPermissionInterceptor extends BaseMultiTableInnerIntercepto @Override protected void processSelect(Select select, int index, String sql, Object obj) { if (select instanceof PlainSelect) { - this.setWhere((PlainSelect) select, (String) obj); + this.setWhere((PlainSelect) select); } else if (select instanceof SetOperationList setOperationList) { List