java spring中如何处理全局异常?

问题描述

目前我正在开发一个小型系统来记录所有未捕获的异常并将它们存储到数据库中以供进一步调试/开发。 为此,我为特定线程使用了 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 的使用。如果我使用构造函数注入(就像在这代码片段中一样):

private LoggedExceptionService service;

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

然后该字段不为空,但是我不能将其声明为异常处理程序,因为我无法将其自动装配到 java 本地方法调用将是:

Thread.setDefaultUncaughtExceptionHandler(new GlobalExceptionHandler());

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

解决方法

将其设为组件并在 @PostContruct 方法中设置 deault 异常处理程序。

@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 成为一个 spring 组件还允许自动装配 service,否则它永远不会被设置。无论如何,我建议您使用 usd 构造函数自动装配:

@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));
    }
}