7.12 Springboot实战项目的业务异常:自定义断言Assert

CSDN成就一亿技术人


前言

上文我分享了全局异常处理的实战经验,其中讲到了业务异常,但还没有在项目中抛出该异常。

本文就带大家在实战项目中抛出该异常,实战场景像开发中经常遇到的:非法调用,业务校验,数据错误,或者业务逻辑错误等等,这里在架构上需要考虑的是高扩展性易维护性,直接抛出会非常散乱,如果需要修改会修改非常多的点,所以我们可以将抛出业务异常统一包装到一个类中,在一个类中统一控制抛出的条件、抛出的业务异常类型、以及异常编码等,也就是本文的主角:自定义断言Assert

上文地址:7.11 SpringBoot实战 全局异常处理 - 深入细节详解


一、什么是断言assert

断言是编程界的一个术语,英文是assert,大概的意思是开发人员提前在指定位置埋了一些假设条件,如果执行到那,条件不成立,那么程序就会中止发生异常,通过这种方式达到程序必须满足开发者预设的条件后才能继续执行的目的!

也就是说,断言会非常明确的给代码执行逻辑提出严格的要求,所以它是提升代码质量非常有效的手段,越是有经验的开发也越会合理的使用断言,所以,这个断言还真得好好用起来哦~


二、为什么要自定义断言Assert?

Java有assert 关键字,就是断言的实现,具体用法很简单,另外Spring也有Assert断言工具类,这里统统都不展开说。

为什么不用这些Assert类呢?

主要的两个点是:成本和灵活

  • 成本是说Assert类的实现门无槛极,内部实现基本都是 if (条件) {抛出异常},所以我们完全有能力自定义Assert工具类!

    扫描二维码关注公众号,回复: 16431060 查看本文章
  • 更重要的是非常灵活,由我们自己组装我们的业务异常和各种技术实现上的异常,统一控制,自由扩展,不管多复杂的场景我们都可以Hold住!

所以,我们先定义几个通用的断言场景,其它的在有场景需要时再添加即可!


三、判空notNull或ifNull

接下来,在common中定义Assert工具类:
在这里插入图片描述

首当其冲要实现的是:判空!它是最常用的断言,基本各种场景都需要判空,再配合全局异常处理,可以非常爽的处理各种异常逻辑!

空的情况又非常多,如果通用的话,比如至少要包括下面这些空:

  • String为null、空串、空格

  • Array/List/Map/Set为null、size()为0

  • 等等

所以,我的实现代码如下:

import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
 * 是否是null 或者 空白
**/
private static boolean isNullOrBlank(Object obj) {
    
    
    if (ObjectUtils.isEmpty(obj)) {
    
    
        return true;
    }
    if (obj instanceof String && !StringUtils.hasText((String)obj)) {
    
    
        return true;
    }
    return false;
}

相信不必过多解释,我知道大家的基础都是非常不错的,接着简单验证一下(当然你可以加更多对象验证):

public static void main(String[] args) {
    
    
    // 测试isNullOrBlank是否符合期望
    // 空
    System.out.println("null:" + Assert.isNullOrBlank(null));
    System.out.println("空串:" + Assert.isNullOrBlank(""));
    System.out.println("空格:" + Assert.isNullOrBlank(" "));
    Assert anAssert = null;
    System.out.println("空对象:" + Assert.isNullOrBlank(anAssert));
    System.out.println("空数组:" + Assert.isNullOrBlank(new byte[]{
    
    }));
    System.out.println("空List:" + Assert.isNullOrBlank(new ArrayList()));
    System.out.println("空Map:" + Assert.isNullOrBlank(new HashMap()));
    System.out.println("空Set:" + Assert.isNullOrBlank(new HashSet()));
    // 非空
    System.out.println("非空String:" + Assert.isNullOrBlank("g"));
    anAssert = new Assert();
    System.out.println("非空对象:" + Assert.isNullOrBlank(anAssert));
    System.out.println("非空数组:" + Assert.isNullOrBlank(Arrays.asList("").toArray()));
    System.out.println("非空List:" + Assert.isNullOrBlank(Arrays.asList("")));
    Map<String, String> map = new HashMap<>();
    map.put("a", "b");
    System.out.println("非空Map:" + Assert.isNullOrBlank(map));
    System.out.println("非空Set:" + Assert.isNullOrBlank(map.entrySet()));
}

在这里插入图片描述

清一色的true和false,完全符合预期!Perfect~

我们第一个断言方法随之而来,show you my code~

/**
 * obj不能为空,如果是空则抛出异常
 **/
public static void notNull(Object obj, String msg) {
    
    
    if (isNullOrBlank(obj)) {
    
    
        throw new BizException(msg);
    }
}

当然,还有另外一种命名方法,就是方法名以if开头,和方法里的if条件对应,你可以根据你的喜好自由命名,如下:

/**
 * obj如果是空则抛出异常
 **/
public static void ifNull(Object obj, String msg) {
    
    
    if (isNullOrBlank(obj)) {
    
    
        throw new BizException(msg);
    }
}

你更喜欢哪种?文末投上你的一票吧~


四、判真isTrue或ifFalse

学会了判空,判真就像苹果从树上掉到地上一样自然:

/**
 * 表达式必须为true,如果不是true则抛出异常
 **/
public static void isTrue(boolean expression, String message) {
    
    
    if (!expression) {
    
    
        throw new BizException(message);
    }
}

同理,另外一种命名方式:

/**
  * 表达式如果不是true则抛出异常
  **/
public static void ifFalse(boolean expression, String message) {
    
    
    if (!expression) {
    
    
        throw new BizException(message);
    }
}

五、判假isFalse或ifTrue

到了这里,我多说一句 好像都是多余的!直接上代码~!

/**
 * 表达式必须为false,如果是true则抛出异常
 **/
public static void isFalse(boolean expression, String message) {
    
    
    if (expression) {
    
    
        throw new BizException(message);
    }
}

/**
 * 表达式如果是true则抛出异常
 **/
public static void ifTrue(boolean expression, String message) {
    
    
    if (expression) {
    
    
        throw new BizException(message);
    }
}

六、应用断言Assert

直接就能用上Assert的吗?
当然!
在之前的实战中,service层直接使用了TgResult作为返回值,这正是我们可以使用Assert的地方。

应用1: BookService.saveBook

比如,BookService的saveBook方法,我们现在就可以直接将返回值从TgResult<Integer>改成Integer了:
在这里插入图片描述

具体修改的代码,你应该一看便懂!
在这里插入图片描述

在这里插入图片描述

应用2: BookBorrowService.examineBookBorrow

这里我就不多解释了,返回值直接可以改成void了,具体判断的替代代码如下,是不是更简洁?
在这里插入图片描述
在这里插入图片描述


最后

== 看到这,觉得有帮助的,刷波666,感谢大家的支持~ ==

想要看更多实战好文章,还是给大家推荐我的实战专栏–>《基于SpringBoot+SpringCloud+Vue前后端分离项目实战》,由我和 前端狗哥 合力打造的一款专栏,可以让你从0到1快速拥有企业级规范的项目实战经验!

具体的优势、规划、技术选型都可以在《开篇》试读!

订阅专栏后可以添加我的微信,我会为每一位用户进行针对性指导!

另外,别忘了关注我:天罡gg ,怕你找不到我,发布新文不容易错过: https://blog.csdn.net/scm_2008

猜你喜欢

转载自blog.csdn.net/scm_2008/article/details/132656559
今日推荐