Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有Java配置的Spring中@Scheduled tasks(启动)的通用异常处理程序_Spring_Spring Boot_Scheduled Tasks_Spring Scheduled - Fatal编程技术网

具有Java配置的Spring中@Scheduled tasks(启动)的通用异常处理程序

具有Java配置的Spring中@Scheduled tasks(启动)的通用异常处理程序,spring,spring-boot,scheduled-tasks,spring-scheduled,Spring,Spring Boot,Scheduled Tasks,Spring Scheduled,我在Spring Boot(1.4.2版)应用程序中有很多计划的任务,我希望使用一个处理程序捕获所有异常,这对于带注释的普通控制器来说是可能的。由于线程问题,此方法不适用于使用@Scheduled annotation定义的任务: @Component public class UpdateJob { @Transactional @Scheduled(cron = "0 1 0 * * *") public void runUpdateUsers() {

我在Spring Boot(1.4.2版)应用程序中有很多计划的任务,我希望使用一个处理程序捕获所有异常,这对于带注释的普通控制器来说是可能的。由于线程问题,此方法不适用于使用@Scheduled annotation定义的任务:

@Component
public class UpdateJob {
    @Transactional
    @Scheduled(cron = "0 1 0 * * *")
    public void runUpdateUsers() {
        userService.updateUsers();
    }

    @ExceptionHandler
    public void handle(Exception e) {
       // some more logic here
       logger.error(e.getMessage());
    }

 }
@ExceptionHandler不适用于@Scheduled方法(事实证明它并不适用)。相反,Spring Boot使用它自己的:

我是否可以替换或提供计划任务的默认异常处理程序?或者切换到我所理解的会进一步传播错误的位置是否有意义(并且是否可能)?是否有其他方法可以仅使用Java配置(无XML)来实现此目标

这不是的重复,因为它明确要求一个基于Java配置的解决方案,而不是基于XML的解决方案(因此在没有任何XML配置的情况下并入Spring Boot项目是不错的)


还有一些答案演示了如何从头配置TaskScheduler。例如,这要求您还定义池大小、最大池大小和队列容量。是一个也需要非常广泛配置的解决方案。显示如何配置其他方面,但不显示如何指定错误处理。但是使用Java配置所需的最小工作量是多少?这样我就可以最大限度地保持Spring启动的默认值(线程池、执行器配置等)

如评论中所述,
@ExceptionHandler
用于Spring MVC控制器

若您想为单个调度器提供异常处理逻辑,最简单和最可维护的方法是将其包装到try-catch块中,并在其中处理错误


如果您想对不同的调度程序应用相同的错误处理程序,请遵循@M.Deinum的建议

下面是一个设置自定义错误处理程序(Spring 2.0.2)的示例:


我认为使用AOP可以解决您的问题

步骤

  • 创建一个名为UpdateJobop的类,并使用@Component和@Aspect注释进行注释
  • 在UpdateJobop类中,创建一个名为all()的方法,并用@Pointcut(“execution(*com.foo.bar.UpdateJob.*(..))进行注释
  • 在UpdateJoBoop类中创建另一个名为afterThrowing(Exception ex)的方法或其他方法,并使用@afterThrowing(pointcut=“all()”,throwing=“ex”)进行注释
  • 打印stacktrace并检查是否捕获了所有异常
  • 供参考: 我已经在个别方法上使用AOP,捕获了它的异常并记录了它,但就我个人而言,到目前为止,我还没有提出您指定的用例。上述解决方案只是一个建议

    @Aspect
    @Component
    public class UpdateJobAOP {
    
        @Pointcut("execution(* com.foo.bar.UpdateJob.*(..))")
        public void all()  {}
    
        @AfterThrowing(pointcut="all()", throwing="ex")
        public void afterThrowing(Exception ex)  {
    
            // Do what you want
            ex.printStackTrace();
    
        }
    
    }
    

    您使用
    PropagatingErrorHandler
    的方法是正确的,但您稍微误解了目的。它会导致异常在堆栈的更上层继续,从而导致计划的任务将来不会运行。此外,它是
    TaskUtils
    的私有文件,因此您无法访问它

    您需要实现自己的
    错误处理程序
    ,但只能有一个处理程序。至少您需要记录异常,因为您不再需要Spring为您记录它

    假设您没有自己的自定义
    TaskScheduler
    bean,要在Spring Boot中创建自己的
    ErrorHandler
    ,请在@Configuration类中实现
    org.springframework.Boot.task.TaskSchedulerCustomizer

    @Override
    public void customize(ThreadPoolTaskScheduler taskScheduler) {
        taskScheduler.setErrorHandler(new CustomErrorHandler());
    }
    
    private static class CustomErrorHandler implements ErrorHandler {
        private static final Logger logger = LoggerFactory.getLogger(CustomErrorHandler.class);
    
        @Override
        public void handleError(Throwable t) {
            logger.error("Scheduled task threw an exception: {}", t.getMessage(), t);
        }
    }
    
    因为
    ErrorHandler
    是一个
    @功能界面
    ,所以您可以执行以下操作:

    taskScheduler.setErrorHandler(t -> { /* Handle exception here */});
    

    (这基于Spring Boot 2.1.8)

    异常处理程序用于Web处理程序方法。请提供理由,是否有任何原因使您不能将异常处理程序用于任何方法或类?术语“web处理程序”适用于ASP.net,可能与ASP.net有所不同?它是webmvc基础设施的一部分。它将与
    @Controller
    一起使用。阅读您链接的javadoc。Spring Boot没有配置任何东西。在配置
    TaskScheduler
    时,设置要在其上使用的
    ErrorHandler
    。@M.Deinum,您能举个例子吗?是否可以与“@Scheduled”批注一起实现?谢谢!这个特定的@ExceptionHandler似乎并不是为此目的而设计的。我只想提供错误处理程序,但不想更改其他执行器属性。我明白,除非我也愿意管理计划程序本身,否则无法为计划任务(作为@Bean?)提供异常处理?请参阅下面关于
    TaskSchedulerCustomizer
    的评论,似乎是一个干净的解决方案。您可以通过在
    @配置中实现
    TaskSchedulerCustomizer
    并仅设置错误处理程序来定制Spring Boot的默认
    TaskScheduler
    。这使您可以保持Spring Boot的默认配置。
    @Override
    public void customize(ThreadPoolTaskScheduler taskScheduler) {
        taskScheduler.setErrorHandler(new CustomErrorHandler());
    }
    
    private static class CustomErrorHandler implements ErrorHandler {
        private static final Logger logger = LoggerFactory.getLogger(CustomErrorHandler.class);
    
        @Override
        public void handleError(Throwable t) {
            logger.error("Scheduled task threw an exception: {}", t.getMessage(), t);
        }
    }
    
    taskScheduler.setErrorHandler(t -> { /* Handle exception here */});