如何更改此 Spring Batch @Scheduled() 注释以指定执行时间和时间?

How to change this Spring Batch @Scheduled() annotation in order to specify execution hour and time?

我正在开发一个执行作业的 Spring 批处理应用程序。使用 Spring CRON 表达式安排作业。

在我的项目中我有这个 SpringBatchExampleJobLauncher class:

@Component
public class SpringBatchExampleJobLauncher {

    private static final Logger LOGGER = LoggerFactory.getLogger(SpringBatchExampleJobLauncher.class);

    private final Job job;
    private final JobLauncher jobLauncher;
    private ExecutionContext executionContext;

    @Autowired
    public SpringBatchExampleJobLauncher(@Qualifier("updateNotaryDistrictsJob") Job job, 
                                         JobLauncher jobLauncher,
                                         ExecutionContext executionContext) {
        this.job = job;
        this.jobLauncher = jobLauncher;
        this.executionContext = executionContext;
    }

    @Scheduled(cron = "0/10 * * * * *")
    public void runSpringBatchExampleJob() throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException {
        LOGGER.info("Spring Batch example job was started");
        
        List<NotaryDistrict> notaryDistrictsList = new ArrayList<NotaryDistrict>();
        executionContext.put("notaryDistrictsList", notaryDistrictsList);
        
        jobLauncher.run(job, newExecution());

        LOGGER.info("Spring Batch example job was stopped");
    }

    private JobParameters newExecution() {
        Map<String, JobParameter> parameters = new HashMap<>();

        JobParameter parameter = new JobParameter(new Date());
        parameters.put("currentTime", parameter);

        return new JobParameters(parameters);
    }
}

在此特定示例中,使用的 CRON 异常是:

@Scheduled(cron = "0/10 * * * * *")

所以作业每 10 秒执行一次。这工作正常,但不适合实际情况。我必须每天在特定的时间和分钟执行我的工作

据此post所示:

还有这个文档: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/support/CronSequenceGenerator.html

我知道,按照以下方式,我可以在每个月的第一天 12:00 下午完成我的工作。

"0 0 12 1 * *"

现在我有两个问题:

  1. 出于测试目的,我必须像每天 18:30 一样执行我的工作(基本上我不仅要指定时间,还要指定必须执行作业的时间. 此外,我希望每天都执行它,而不是在前一个表达式指定的月份的第一天)。如何修改此 CRON 表达式以获得所需的行为?

  2. 对于下一个生产阶段,我必须更改此行为,以便在特定周(例如每 2 周)的特定日期(例如星期一)执行我的工作小时和时间。例如:作业必须在第一个星期一和每月的第三个 02:30 下午执行。如何修改此 CRON 表达式以获得所需的行为?

谢谢

Spring documentation 开始,Cron 表达式的格式为:

 ┌───────────── second (0-59)
 │ ┌───────────── minute (0 - 59)
 │ │ ┌───────────── hour (0 - 23)
 │ │ │ ┌───────────── day of the month (1 - 31)
 │ │ │ │ ┌───────────── month (1 - 12) (or JAN-DEC)
 │ │ │ │ │ ┌───────────── day of the week (0 - 7)
 │ │ │ │ │ │          (or MON-SUN -- 0 or 7 is Sunday)
 │ │ │ │ │ │
 * * * * * *
  1. 你可以用0 30 18 * * *实现第一种情况。星号 * 在 cron 表达式中表示 every
  2. 为此您可以使用 0 30 14 ? * MON#1,MON#3MON#X 表示该月的第 X 个星期一。在这种情况下,我们将 ? 用于日期字段,因为 first/third 星期一落在一个月中的哪一天并不重要。 ?表示没有具体值。

关于两个问题:

首先,对于这种情况,您必须避免将 cron 表达式直接放在注释中:

@Scheduled(cron = "0/10 * * * * *") // CURRENT

获得解决方案的一个步骤是在 application.yml 中定义一个 属性,例如:

cron:
    expresion: 0/10 * * * * *

代码:

@Scheduled(cron = "${cron.expression}")

这样做,您可以根据环境获得一个 application.yml,即:application-prod.yml 与生产 cron,以及 运行 它与 prod 配置文件。或者甚至在启动时通过命令行覆盖 属性:

java -jar your-app.jar --cron.expression=0/15 * * * * *

相同的测试用例,您将拥有您的应用程序-test.yml 和经过调整的 属性 用于测试。