Sptring Batch:在初始化Spring Boot上下文期间处理异常

时间:2018-08-02 09:49:30

标签: spring-boot spring-batch

在Spring Boot上下文初始化期间,有什么方法可以处理异常?

我的情况是在作业执行过程中处理错误,并根据发生的异常进行一些工作。

例如,我的工作由读者和作家组成。读取器和写入器使用以下属性初始化:rootFolder,inFolder,outFolder。这个简单的工作从/rootFolder/inFolder/test.txt读取文件,并将数据写入rootFolder / outFolder / test.txt。

我将JobExecutionListener设置为在作业完成后调用,并在作业失败时分析错误。

但是,如果属性错误,则在作业开始之前会发生异常(InvalidPathException或NullPointerException)(因此将不会调用侦听器)。而且我无法分析错误。

是否可以添加用于侦听和分析错误的常规侦听器?

代码示例配置类:

@Configuration
public class JobConfiguration {

   @Autowired
   public JobConfiguration(JobSpecificProperties properties) {
       this.properties = properties;
   }

   private final JobSpecificProperties properties;

   @Bean
   public Job job(JobBuilderFactory jobBuilderFactory, Step step) {
       return jobBuilderFactory.get("jobName")
               .incrementer(new RunIdIncrementer())
               .listener(new SystemExitOnFailureJobExecutionListener())
               .start(step)
               .build();
   }

   @Bean
   public Step step(StepBuilderFactory stepBuilderFactory,
                 ItemReader<String> itemReader,
                 ItemWriter<String> itemWriter) {
       return stepBuilderFactory.get("stepName")
               .<String, String>chunk(Integer.MAX_VALUE)
               .reader(itemReader)
               .writer(itemWriter)
               .build();
   }

   @Bean
   public ItemReader<String> itemReader() {
       FlatFileItemReader<String> reader = new FlatFileItemReader<>();
       reader.setStrict(false);
       reader.setLineMapper((string, index) -> string);
       reader.setResource(new FileSystemResource(Paths.get(properties.getRootFolder(), properties.getInFolder()).resolve("test.txt").toString()));

       return reader;
   }

   @Bean
   public ItemWriter<String> itemWriter() {
       FlatFileItemWriter<String> writer = new FlatFileItemWriter<>();
       writer.setLineAggregator(string -> string);
       writer.setResource(new FileSystemResource(Paths.get(properties.getRootFolder(), properties.getOutFolder()).resolve("test.txt").toString()));

       return writer;
   }
}

代码示例侦听器类:

@Slf4j
public class SystemExitOnFailureJobExecutionListener extends JobExecutionListenerSupport {
    @Override
    public void afterJob(JobExecution jobExecution) {
        if (jobExecution.getStatus() == BatchStatus.FAILED) {
            if (jobExecution.getAllFailureExceptions().get(0) instanceof NullPointerException){
                log.error("some_message_1");
                //TODO: Do something
                System.exit(2);
            } else if (jobExecution.getAllFailureExceptions().get(0) instanceof InvalidPathException){
                log.error("some_message_2");
                //TODO: Do something
                System.exit(3);
            }

            //TODO: Do something by default
            System.exit(1);
        }
   }
}

代码示例属性类:

@Getter
@Setter
@ConfigurationProperties("job.parameter")
public class JobSpecificProperties {
    private String rootFolder;
    private String outFolder;
    private String inFolder;
}

主要应用程序类:

@SpringBootApplication
@EnableBatchProcessing
@EnableConfigurationProperties(JobSpecificProperties.class)
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

1 个答案:

答案 0 :(得分:0)

我希望扩展类AlwaysSkipItemSkipPolicy,以便在作业/步骤级别使用此类。

@Override
public boolean shouldSkip(java.lang.Throwable t, int skipCount){
     if(t instanceof NonSkippableReadException){
                return true;
     }
     return false;
}

有关处理零件的更多信息,请通过

https://docs.spring.io/spring-batch/4.1.x/reference/html/step.html

public interface SkipListener<T,S> extends StepListener {

    void onSkipInRead(Throwable t);
    void onSkipInProcess(T item, Throwable t);
    void onSkipInWrite(S item, Throwable t);

}

或创建方法并使用相应的注释对其进行注释:

@OnSkipInRead

@OnSkipInWrite

@OnSkipInProcess