前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >return 语句竟然跳不出 for 循环?怎么肥事?

return 语句竟然跳不出 for 循环?怎么肥事?

作者头像
江南一点雨
发布2022-05-19 12:12:07
5730
发布2022-05-19 12:12:07
举报
文章被收录于专栏:玩转JavaEE

松哥最近正在录制 TienChin 项目视频~采用 Spring Boot+Vue3 技术栈,里边会涉及到各种好玩的技术,小伙伴们来和松哥一起做一个完成率超 90% 的项目,戳戳戳这里-->TienChin 项目配套视频来啦


今天和小伙伴们聊一个简单的话题,是有一个小伙伴在星球上提的问题,问题不难,但是不熟悉的小伙伴可能会出错,所以简单说一下。

先来看看这个小伙伴是怎么提问的:

老实说,有时候我真的会被小伙伴们的提问感动到! 这年头能把问题这么详细列出来的人真的不多了。松哥微信每天也有不少小伙伴在提问,有的问题就一句话,看了也不知道想问啥,那我也没法回复,我就不贴图了,免得有小伙伴对号入座。

总之这个小伙伴这个提问特别好,我看完文字看完图之后,基本上就已经知道发生什么事了。

他出问题的代码在这里:

这个问题其实这块就是 vhr 中的动态权限问题,小伙伴们知道,vhr 的权限可以动态设置,也就是我们可以通过修改数据库中的表,来动态调整每一个接口需要什么样的权限,vhr 里相关代码主要涉及到三个类:

  • https://github.com/lenve/vhr/blob/master/vhr/vhrserver/vhr-web/src/main/java/org/javaboy/vhr/config/CustomFilterInvocationSecurityMetadataSource.java
  • https://github.com/lenve/vhr/blob/master/vhr/vhrserver/vhr-web/src/main/java/org/javaboy/vhr/config/CustomUrlDecisionManager.java
  • https://github.com/lenve/vhr/blob/master/vhr/vhrserver/vhr-web/src/main/java/org/javaboy/vhr/config/SecurityConfig.java

这三个类的实现细节在 vhr 中都有详细的介绍,这里我就不细说了。这里就简单说说每个类的作用:

  • CustomFilterInvocationSecurityMetadataSource:这个是自定义的获取元数据的类,作用是根据请求的 URL 地址,分析出这个请求所需要的角色。
  • CustomUrlDecisionManager:这是一个决策器,按理说决策器需要配合投票器一起来使用,但是我这里简化了步骤,直接在决策器中做了判断,就没用投票器了,决策器在执行过程中如果抛出了异常,那么就是权限不足,如果决策器能够正常执行不抛出任何异常,那么就说明权限没问题。
  • SecurityConfig:这就是 Spring Security 的配置类,在这个配置类中可以通过对象后置处理器 ObjectPostProcessor 来动态修改一个 Bean,上面两个对象就是通过 ObjectPostProcessor 添加到相应实例中的。

那么这个小伙伴出问题的类就是决策器,我们再来看看他这一张图片:

decide 方法就是决策方法,这个方法第一个参数 Authentication 参数重保存了当前用户的信息,包括当前用户的角色啥的;第三个参数是一个集合,里边是当前请求需要的角色信息。

现在就在 decide 方法中做比对,如果当前用户具备当前请求所需要的角色,那么就没问题,如果当前用户不具备当前请求所需要的角色,那么就抛出异常。

仔细看你发现他这个逻辑也没啥问题,而且看下面的日志也打印出来了,说明 if 分支也进去了,所以问题就出在了这个 return 上面。

小伙伴们看这里的 return 在 forEach 中,而不是我们常见的 for 循环中,那么这歌 forEach 和 for 有啥不同呢?

这个 forEach 是 lambda 表达式相关的内容,forEach 的参数是一个消费者,也就是消费一个数据,类似下面这样:

代码语言:javascript
复制
List<String> list = new ArrayList<>();
list.forEach(new Consumer<String>() {
    @Override
    public void accept(String s) {
        
    }
});

那么你想一下,accept 方法中出现一个 return,那么仅仅只能终止当前方法的执行,并不影响循环整体的执行,即并不能提前终止循环。

现在就真相大白了,如果匹配到权限是满足的,提前终止的 return 语句没生效,方法最后一句异常还是会抛出来。

所以改成这样就行啦:

好啦,最后再盲猜一下为什么这个小伙伴会出现这个错误。在 vhr 视频中,我是前后端都手把手教大家写的,视频也会写前端代码,前端有一个 forEach,就是真正的 for 循环,而且前端的箭头函数跟后端的 Lambda 也挺像的,估计小伙伴可能看到前端的,以为后端也能这么用(纯瞎猜~。


松哥最近正在录制 TienChin 项目视频~采用 Spring Boot+Vue3 技术栈,里边会涉及到各种好玩的技术,小伙伴们来和松哥一起做一个完成率超 90% 的项目,戳戳戳这里-->TienChin 项目配套视频来啦


本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 江南一点雨 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档