Java 8默认方法的实践过程

举报
码农小胖哥 发表于 2022/03/31 00:53:02 2022/03/31
【摘要】 Spring Boot 2.4.x已经用了一年多,借着新业务调整的时机把依赖升级到最新的Spring Boot 2.6.5,在升级的时候遇到一个优化点,非常有意思,我觉得值得拿出来分享一下。 public interface Checker {      ...

20c030a93dd9387bec0302ca9c4e8a4a.gif

Spring Boot 2.4.x已经用了一年多,借着新业务调整的时机把依赖升级到最新的Spring Boot 2.6.5,在升级的时候遇到一个优化点,非常有意思,我觉得值得拿出来分享一下。

public interface Checker {
 
    boolean check(Authentication authentication, HttpServletRequest request);
 
    Predicate<HttpServletRequest> whitePredicate();
}

上面接口是用来做动态权限的,它包含了两个方法

  • check 用来检测当前请求是否和当前认证信息一致

  • whitePredicate 是开放的一个白名单断言,方便放行一些请求的。

最开始whitePredicate 因为业务有白名单配置,因此没什么问题,都感觉这个接口设计很好。但是推广到其它项目的时候就不太优雅了,不是所有的业务都有白名单接口,无奈就给个白名单一个默认的实现:

public Predicate<HttpServletRequest> whitePredicate() {
        // false 表示没白名单
        return request -> false;
    }

false表示没白名单。

后面升级的过程中使用了Java 8出现的接口默认方法,把白名单作为一种默认的情况抽象了出来。这样自然Checker就成为了函数式接口:

@FunctionalInterface
public interface Checker {
 
    boolean check(Authentication authentication, HttpServletRequest request);
 
    default Predicate<HttpServletRequest> whitePredicate() {
        return request -> false;
    }
}

这里还有一个痛点,每次实现check都要编写whitePredicate对请求访问进行白名单断言的逻辑,不然这个断言方法就成了摆设:

public boolean check(Authentication authentication, HttpServletRequest request) {
        // 白名单断言
        if (whitePredicate().test(request)) {
            return true;
        }
        // 处理逻辑
    }

非常不方便,而且whitePredicate方法并没体现在设计意图中,因此又使用了默认方法进行了抽象,把流程固化:

@FunctionalInterface
public interface Checker {
 
    default boolean check(Authentication authentication, HttpServletRequest request) {
        if (whitePredicate().test(request)) {
            return true;
        }
        return doCheck(authentication, request);
    }

    boolean doCheck(Authentication authentication, HttpServletRequest request);
 
    default Predicate<HttpServletRequest> whitePredicate() {
        return request -> false;
    }

}

check的流程就被固化下来了,白名单方法一定会先执行,剩下的检测委托给doCheck方法来处理。这样设计更加合理紧凑,而且还保证了Checker依旧是一个函数式接口,Java 8 默认方法的意义应该就在这里。或许一开始就应该这样处理,只不过当时没考虑到去固化流程。

从这里可以看得出,其实好的设计并不是开始就有的,经过一次次的迭代和优化、抽象归纳才会有现在的样子。另外也需要结合一些新技术、新特性。有时候不是你集成了新技术就是新技术,只有用了新技术才是新技术。你对此有什么看法?欢迎留言讨论。

ed55217b9111a3ce7adf27d6799daa12.gif

文章来源: felord.blog.csdn.net,作者:码农小胖哥,版权归原作者所有,如需转载,请联系作者。

原文链接:felord.blog.csdn.net/article/details/123836099

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。