所有作业完成后的春季批处理触发过程

时间:2018-06-21 11:29:49

标签: java spring spring-batch

我有一个带有一系列作业的Spring Batch应用程序。我想在所有工作完成后发送电子邮件,但是我不确定执行此操作的最佳方法。我正在考虑的选项是:

  1. 以特定顺序运行作业,并修改上一个作业的JobListener,以便它将发送电子邮件。不利的一面是,如果在批次的末尾添加其他作业,将无法正常工作。
  2. 添加一个新作业,该作业将发送电子邮件并订购这些作业,确保此附加作业最后运行。
  3. 是否有任何内置的spring-batch结构会在整个批处理完成时触发?

最后一个选择是我的首选解决方案,所以我的问题是,是否有任何侦听批处理完成的spring-batch类(类似于JobExecutionListenerSupport或Step Listener)?

2 个答案:

答案 0 :(得分:1)

如果我的理解正确,那么您有一份工作。在这种情况下,您可以使用一系列JobStep类型的步骤(委托给一个作业)来定义一个封闭的作业。然后,您可以在附件作业中注册JobExecutionListener。完成所有步骤(又称为子任务)后,将调用此侦听器。

此处有关JobStep的更多详细信息:https://docs.spring.io/spring-batch/4.0.x/api/org/springframework/batch/core/step/job/JobStep.html

答案 1 :(得分:1)

不。我不知道任何侦听整个批次完成情况的批次监听器。

我有两种选择适合您。两者都可以让您坚持使用Spring。

(1)如果您的应用程序是永久性的(例如,像Web服务器一样),则可以注入自定义jobLauncher,抢占TaskExecutor并等待其完成(通过简单的计数器计算afterJob函数或需要提交所有作业的一定时间(不一定启动)中的回调。

添加这样的配置类:

@Configuration
class JobConfiguration implements InitializingBean {
    TaskExecutor taskExecutor;

    @Bean TaskExecutor taskExecutor () {
        // here, change to your liking, in this example
        // I put a SyncTaskExecutor
        taskExecutor = new SyncTaskExecutor();
        return taskExecutor;
    }

    @Bean 
    public JobLauncher jobLauncher(@Autowired JobRepository jobRepository,
        @Autowired TaskExecutor taskExecutor) {
        SimpleJobLauncher launcher = new SimpleJobLauncher();
        launcher.setJobRepository(jobRepository);
        launcher.setTaskExecutor(taskExecutor);
        return launcher;
    }

    List<Job> jobs; 

    // I don't use this in this example
    // however, jobs.size() will help you with the countdown latch
    @Autowired public void setJobs (List<Job> jobs) {
        this.jobs = jobs;
    }

    @AfterPropertiesSet
    public void init () {
        // either countdown until all jobs are submitted 
        // or sleep a finite amount of time
        // in this example, I'll be lazy and just sleep
        Thread.sleep(1 * 3600 * 1000L); // wait 1 hour
        taskExecutor.shutdown();
        try {
            taskExecutor.awaitTermination();
        } catch (Exception e) {}
        finally {
            // send your e-mail here. 
        }
    }
}

(2)如果您的应用程序在完成所有作业后停止,则只需按照this发送电子邮件即可。

为了完整性,我重复几行代码:

public class TerminateBean {

    @PreDestroy
    public void onDestroy() throws Exception {
        // send out e-mail here
    }
}

我们还必须添加这种类型的bean:

@Configuration
public class ShutdownConfig {

    @Bean
    public TerminateBean getTerminateBean() {
        return new TerminateBean();
    }
}