奇巧淫技,使用aop编写抛出随机异常

在开发测试过程中,有时候我们需要抛出一个异常来测试我们的代码.我们往往的做法是在代码中嵌入一段代码来实现,完成功能后再将其注释或者删除,等到下次又要测试的时候,又得重新加入.

int num =  ThreadLocalRandom.current().nextInt(100);
        if(num%10 ==0){
            throw new RuntimeException("随机异常");
        }

通过aop,加入注解的方式,以一种优雅的方式,随机参数异常.并可以通过Profile,来指定是否启用.

1.0

public @interface RandomlyThrowsException {
}
@Aspect
public class RandomlyThrowsExceptionAspect implements Ordered {
    private final int order;

    public RandomlyThrowsExceptionAspect(int order) {
        this.order = order;
    }

    @Override
    public int getOrder() {
        return order;
    }


    @Around("@annotation(com.github.superwen0001.practice.exception.RandomlyThrowsException)")
    public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        int num = ThreadLocalRandom.current().nextInt(100);
        if (num % 10 == 0) {
            throw new RuntimeException("随机异常");
        }
        return joinPoint.proceed();
    }

}

@Configuration
public class ComonConfig {

    @Bean
    public RandomlyThrowsExceptionAspect randomlyThrowsExceptionAspect() {
        final int order = Byte.MAX_VALUE;
        RandomlyThrowsExceptionAspect randomlyThrowsExceptionAspect = new RandomlyThrowsExceptionAspect(order);
        return randomlyThrowsExceptionAspect;
    }
}

@RestController
public class DemoController {

    @GetMapping("t1")
    @RandomlyThrowsException
    public String t1(){
        return "t1";
    }
}

当访问 http://127.0.0.1:8080/t1, 访问多次出现错误页面

1.1 可以指定异常的类型,异常的message

更进一步,可以指定产生的概率等等

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface RandomlyThrowsException {
    String message() default "";

    Class<? extends Throwable>[] throwable() default RuntimeException.class;

}

@Aspect
public class RandomlyThrowsExceptionAspect implements Ordered {
    private final int order;

    public RandomlyThrowsExceptionAspect(int order) {
        this.order = order;
    }

    @Override
    public int getOrder() {
        return order;
    }


    @Around("@annotation(com.github.superwen0001.practice.exception.RandomlyThrowsException)")
    public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        int num = ThreadLocalRandom.current().nextInt(100);
        if (num % 10 == 0) {
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            RandomlyThrowsException randomlyThrowsException = method.getAnnotation(RandomlyThrowsException.class);
            String message = randomlyThrowsException.message();
            Class[] classes = randomlyThrowsException.throwable();
            Class clazz = classes[ThreadLocalRandom.current().nextInt(classes.length)];
            //注意,自定义的异常一定要有带一个String参数的构造函数
            Constructor c = clazz.getConstructor(String.class);
            throw (Throwable) c.newInstance(message);
        }
        return joinPoint.proceed();
    }

}

public class DemoException extends RuntimeException {
    public DemoException() {
    }

    public DemoException(String message) {
        super(message);
    }

    public DemoException(String message, Throwable cause) {
        super(message, cause);
    }

    public DemoException(Throwable cause) {
        super(cause);
    }

    public DemoException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}
@RestController
public class DemoController {

    @GetMapping("t1")
    @RandomlyThrowsException(message = "测试随机异常", throwable = DemoException.class)
    public String t1() {
        return "t1";
    }
}

代码地址: https://github.com/superwen0001/practice/tree/dev/aop-random-exception

转载于:https://my.oschina.net/superwen/blog/1504731

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值