SpringBoot数据权限使用预扫描提升代码性能

问题说明

原本数据权限的忽略方案是每次在查询之前去查找当前类上或者方法上是否有忽略注解的权限,优化之后每次项目启动时将所有配置了忽略数据权限注解的类加载到ConcurrentHashMap中,在有查询过来是直接去缓存中读取

/**
 * 方法或类(名称) 与 注解的映射关系缓存
 */
private final Map<String, DataPermission> dataPermissionCacheMap = new ConcurrentHashMap<>();

原本方案

mappedStatementId存储的是mapper的类路径,再通过反射去找类上和方法上注解是否忽略
在这里插入图片描述
运行时调用方法
在这里插入图片描述
查找是否存在忽略注解
在这里插入图片描述

改进后方案

通过yml配置的包路径,在项目启动时注入扫描

在这里插入图片描述

/**
 * 通过 mapperPackage 设置的扫描包 扫描缓存有注解的方法与类
 */
private void scanMapperClasses(String mapperPackage) {
    PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
    CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
    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);
            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());
    }
}

扫描完添加到缓存中

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);
    }
}

这样每次查询过来时调用此方法即可

   public DataPermission getDataPermission(String mapperId) {
        if (dataPermissionCacheMap.containsKey(mapperId)) {
            return dataPermissionCacheMap.get(mapperId);
        }
        String clazzName = mapperId.substring(0, mapperId.lastIndexOf("."));
        if (dataPermissionCacheMap.containsKey(clazzName)) {
            return dataPermissionCacheMap.get(clazzName);
        }
        return null;
    }

在这里插入图片描述

  • 15
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值