在每个 Spring 计划 (@Scheduled) 运行之前重置状态 [英] Reset state before each Spring scheduled (@Scheduled) run

查看:70
本文介绍了在每个 Spring 计划 (@Scheduled) 运行之前重置状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个需要每天运行的 Spring Boot Batch 应用程序.它读取每日文件,对其数据进行一些处理,并将处理后的数据写入数据库.在此过程中,应用程序持有一些状态,例如要读取的文件(存储在 FlatFileItemReaderJobParameters 中)、当前运行的日期和时间、一些文件用于比较读取项目等的数据.

I have a Spring Boot Batch application that needs to run daily. It reads a daily file, does some processing on its data, and writes the processed data to a database. Along the way, the application holds some state such as the file to be read (stored in the FlatFileItemReader and JobParameters), the current date and time of the run, some file data for comparison between read items, etc.

调度的一种选择是使用 Spring 的 @Scheduled 如:

One option for scheduling is to use Spring's @Scheduled such as:

@Scheduled(cron = "${schedule}")
public void runJob() throws Exception {
    jobRunner.runJob(); //runs the batch job by calling jobLauncher.run(job, jobParameters);
}

这里的问题是在运行之间保持状态.所以,我必须更新要读取的文件,运行的当前日期和时间,清除缓存的文件数据等.

The problem here is that the state is maintained between runs. So, I have to update the file to be read, the current date and time of the run, clear the cached file data, etc.

另一种选择是通过 unix cron 作业运行应用程序.这显然将满足在运行之间清除状态的需要,但我更喜欢将作业调度与应用程序而不是操作系统联系起来(并且更喜欢它与操作系统无关).可以在 @Scheduled 运行之间重置应用程序状态吗?

Another option is to run the application via a unix cron job. This will obviously meet the need to clear state between runs but I prefer to tie the job scheduling to the application instead of the OS (and prefer it to OS agnostic). Can the application state be reset between @Scheduled runs?

推荐答案

Thomas 的方法似乎是一个合理的解决方案,这就是我赞成它的原因.缺少的是如何在春季批处理作业的情况下应用它.因此我稍微调整了他的例子:

Thomas' approach seems to be a reasonable solution, that's why I upvoted it. What is missing is how this can be applied in the case of a spring batch job. Therefore I adapted his example little bit:

@Component
public class JobCreatorComponent {


    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public Job createJob() {
       // use the jobBuilderFactory to create your job as usual
       return jobBuilderFactory.get() ...
    }
}

你的组件与启动方法@成分公共类 ScheduledLauncher {

your component with the launch method @Component public class ScheduledLauncher {

   @Autowired
   private ... jobRunner;

   @Autwired
   private JobCreatorComponent creator;

@Scheduled(cron = "${schedule}")
public void runJob() throws Exception {

    // it would probably make sense to check the applicationContext and
    // remove any existing job

    creator.createJob(); // this should create a complete new instance of 
                         //  the Job
    jobRunner.runJob(); //runs the batch job by calling jobLauncher.run(job, jobParameters);
}

我还没有尝试过代码,但这是我会尝试的方法.

I haven't tried out the code, but this is the approach I would try.

在构建作业时,重要的是要确保此作业中使用的所有读取器、处理器和写入器也是全新的实例.这意味着,如果它们没有被实例化为纯 Java 对象(而不是作为 spring bean)或作为具有step"范围的 spring bean,则必须确保始终使用新实例.

When constructing the job, it is important to ensure that all reader, processors and writers used in this job are complete new instances as well. This means, if they are not instantiated as pure java objects (not as spring beans) or as spring beans with scope "step" you must ensure that always a new instance is used.

如何处理 SingeltonBeans有时无法阻止单例 bean,在这些情况下,必须有一种方法来重置"它们.

Edited: How to handle SingeltonBeans Sometimes singleton beans cannot be prevented, in these cases there must be a way to "reset" them.

一个简单的方法是定义一个接口ResetableBean",其中包含由此类 bean 实现的重置方法.然后可以使用 Autowired 收集所有此类 bean 的列表.

An simple approach would be to define an interface "ResetableBean" with a reset method that is implemented by such beans. Autowired can then be used to collect a list of all such beans.

@Component
public class ScheduledLauncher {

    @Autowired
    private List<ResetableBean> resetables;

    ...

    @Scheduled(cron = "${schedule}")
    public void runJob() throws Exception {
       // reset all the singletons
       resetables.forEach(bean -> bean.reset());
       ...

这篇关于在每个 Spring 计划 (@Scheduled) 运行之前重置状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆