【问题标题】:How to handle global exceptions in java spring?java spring 如何处理全局异常?
【发布时间】:2021-08-19 03:03:19
【问题描述】:

目前我正在开发一个小型系统来记录所有未捕获的异常并将它们存储到数据库中以供进一步调试/开发。 为此,我将 UncaughtExceptionHandler 用于特定线程:

public class GlobalExceptionHandler implements Thread.UncaughtExceptionHandler{

    @Autowired
    private LoggedExceptionService service;


    public GlobalExceptionHandler() {
    }

    @Override
    public void uncaughtException(Thread t, Throwable e) {
        System.err.println("IN UNCAUGHTEXCEPTION METHOD");
        this.service.saveException(new LoggedException(e));
    }
}

正如您所见,service 字段已注入,当我捕获异常时,我会收到 NullPointerException,因为该字段为空。

主要问题是 GlobalExceptionHandler 的使用。如果我使用构造函数注入(如在此代码 sn-p 中):

private LoggedExceptionService service;

@Autowired
public GlobalExceptionHandler(LoggedExceptionService service) {
this.service = service;
}

那么该字段不为空,但是我不能将它声明为异常处理程序,因为我不能将它自动装配到 java-native 方法。电话是:

Thread.setDefaultUncaughtExceptionHandler(new GlobalExceptionHandler());

是否有可能将处理程序自动连接到线程方法,或者有什么好方法?

【问题讨论】:

    标签: java spring exception constructor-injection


    【解决方案1】:

    使其成为一个组件并在@PostContruct 方法中设置derault 异常处理程序。

    @Component
    public class GlobalExceptionHandler implements Thread.UncaughtExceptionHandler{
    
        @Autowired
        private LoggedExceptionService service;
    
    
        public GlobalExceptionHandler() {
        }
    
        @PostContruct
        public void init(){
            Thread.setDefaultUncaughtExceptionHandler(this);
        }
    
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            System.err.println("IN UNCAUGHTEXCEPTION METHOD");
            this.service.saveException(new LoggedException(e));
        }
    }
    

    这允许您自动设置处理程序,因为组件中带有 @PostContruct 注释的方法在启动时会自动执行。

    使GlobalExceptionHandler 成为一个弹簧组件还允许自动装配service,否则将永远不会设置。无论如何,我建议你使用构造函数自动装配:

    @Component
    public class GlobalExceptionHandler implements Thread.UncaughtExceptionHandler{
    
        private final LoggedExceptionService service;
    
        @Autowired // @Autowired is actually not necessary if this is the only constructor
        public GlobalExceptionHandler(LoggedExceptionService service) {
            this.service=service
        }
    
        @PostContruct
        public void init(){
            Thread.setDefaultUncaughtExceptionHandler(this);
        }
    
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            System.err.println("IN UNCAUGHTEXCEPTION METHOD");
            this.service.saveException(new LoggedException(e));
        }
    }
    

    【讨论】:

    • 谢谢! PostConstruct 非常好用。我将注入更改为构造函数注入。编辑:会尽快接受。
    • 大声笑我正在将其添加到答案中。
    • 嗯,我想我更快了 =P 谢谢你,你让我开心:)
    猜你喜欢
    • 2018-07-19
    • 2016-11-18
    • 2010-12-05
    • 1970-01-01
    • 2013-04-02
    • 2016-11-03
    • 1970-01-01
    • 2018-11-19
    • 2014-07-17
    相关资源
    最近更新 更多