如何处理javaspring中的全局异常?

How to handle global exceptions in 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-native 方法。调用将是:

Thread.setDefaultUncaughtExceptionHandler(new GlobalExceptionHandler());

是否有可能将处理程序自动装配到线程方法或者什么是好的方法?

使其成为一个组件并在 @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 成为 spring 组件还允许自动装配 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));
    }
}