你程序中的异常用对了么? 一个属性大幅减少系统的异常堆栈信息

本文讨论了SpringSecurity框架中的异常处理问题,尤其是如何通过控制`enableSuppression`和`writableStackTrace`参数来减少不必要的堆栈跟踪信息,以优化生产环境的日志输出。
摘要由CSDN通过智能技术生成

         使用Spring Security的朋友们有没有注意到这个框架的异常特别多?例如用户密码错误、密码过期、权限不足等等。控制台上打印着一堆异常堆栈信息,这不但覆盖了有价值的日志,也大大降低了程序的性能,而且这些错误堆栈信息自身的价值很小。

        有没有一种方式避免打印这些异常堆栈呢?其实RuntimeException中有两个非常重要的参数:

  1. enableSuppression:指示是否将异常屏蔽(suppress),默认值为true,启用抑制的。当创建一个异常对象时,可以选择启用或禁用异常抑制。如果启用了异常抑制,那么在一个异常(称为“主异常”)抛出时,如果另一个异常(称为“被抑制的异常”)也发生,则被抑制的异常会被添加到主异常的“抑制异常”列表中。这样做的目的是为了记录被抑制的异常,同时仍然抛出主异常以便进行处理。

  2. writableStackTrace:指示是否保留堆栈跟踪信息。如果设置为true,则表示保留堆栈跟踪信息;如果设置为false,则表示不保留堆栈跟踪信息。默认情况下设置为true。如果将其设置为false,则可以在异常对象中保存空的堆栈跟踪信息,从而减少填充异常对象所需的空间和时间。

运行如下代码,观察修改writableStackTrace的效果:

public class Base1Exception extends RuntimeException {
    public Base1Exception() {
        super();
    }
       
    public Base1Exception(String message) {
        // 第四个参数为: writableStackTrace
        super(message, null, false, true);
    }
}

public class Base2Exception extends RuntimeException {
    public Base2Exception() {
        super();
    }
    public Base2Exception(String message) {
        // 第四个参数为: writableStackTrace
        super(message, null, true, true);
    }
    public Base2Exception(String message, Throwable t) {
        // 第四个参数为: writableStackTrace
        super(message, t, false, true);
    }
}

public class Demo1Application {

    public static void main(String[] args) {
        m1();
    }
    public static void m1() {
        m2();
    }
    public static void m2() {
        m3();
    }
    public static void m3() {
        m4();
    }
    public static void m4() {
        try {
            throw new Base1Exception("Base1Exception 异常抛出");
        } catch (Exception e) {
            throw new Base2Exception("Base2Exception 异常抛出", e);
        }
    }
}

 

writableStackTrace=true (默认值) 的效果:

Exception in thread "main" com.example.demo.Base2Exception: Base2Exception 异常抛出
	at com.example.demo.Demo1Application.m4(Demo1Application.java:26)
	at com.example.demo.Demo1Application.m3(Demo1Application.java:19)
	at com.example.demo.Demo1Application.m2(Demo1Application.java:15)
	at com.example.demo.Demo1Application.m1(Demo1Application.java:10)
	at com.example.demo.Demo1Application.main(Demo1Application.java:6)
Caused by: com.example.demo.Base1Exception: Base1Exception 异常抛出
	at com.example.demo.Demo1Application.m4(Demo1Application.java:24)
	... 4 more

writableStackTrace=false的效果:

Exception in thread "main" com.example.demo.Base2Exception: Base2Exception 异常抛出
Caused by: com.example.demo.Base1Exception: Base1Exception 异常抛出

由此可以发现, writableStackTrace有效的减少了日志的输出量。因此,建议在生产环境启用异常屏蔽和关闭一些业务异常的堆栈跟踪信息。但很遗憾,Spring Security 认证异常类并未重写 RuntimeException 的所有构造方法,特别是包含 enableSuppression 和 writableStackTrace 两个参数的构造方法。这导致 Spring Security 打印的日志特别多。 因此可以在你自己的工程中,通过覆写RuntimeException的所有构造方法,避免一些无效的堆栈打印。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT 行者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值