为Spring @Scheduled提供时区?

问题描述 投票:35回答:4

如何为基于Spring的@Scheduled cron作业配置时区?

背景:

我有一份工作,每天执行一次,比如下午2点,使用Spring的@Scheduled注释:

@Scheduled(cron = "0 0 14 * * *")
public void execute() {
    // do scheduled job
}

问题是不同服务器之间的下午2点不同,因为Spring在TimeZone.getDefault() internally上使用。此外,JavaDocTimeZone.getDefault()指出:

获取此主机的默认TimeZone。默认TimeZone的来源可能因实施而异。

换句话说,不确定时区。它可能取决于JVM实现,服务器时区配置,服务器位置和/或其他未知因素。因此,cron作业在不同服务器上的不同时间触发,除非有办法明确设置应该使用哪个时区?

我使用的是Spring 3.2.2。


更新

截至今年春季,Spring Jira问题SPR-10456已经解决。因此,@Scheduled注释具有新的zone属性,正是出于此目的。

java spring cron timezone scheduling
4个回答
28
投票

事实证明,我无法使用@Scheduled注释,但我实施了解决方法。在SchedulingConfigurer的JavaDoc中声明:

[SchedulingConfigurer]通常用于设置在执行计划任务时使用的特定TaskScheduler bean,或者用于以编程方式注册计划任务,而不是使用@Scheduled注释的声明性方法。

接下来,我更改了cron作业以实现Runnable接口,然后更新了我的配置文件以实现SchedulingConfigurer,请参见下文:

@Configuration
@EnableScheduling
@ComponentScan("package.that.contains.the.runnable.job.bean")
public class JobConfiguration implements SchedulingConfigurer {

    private static final String cronExpression = "0 0 14 * * *";
    private static final String timeZone = "CET";

    @Autowired
    private Runnable cronJob;

    @Bean
    CronTrigger cronTrigger() {
        return new CronTrigger(cronExpression, TimeZone.getTimeZone(timeZone));
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.addCronTask(new CronTask(job, cronTrigger()));
    }
}

请阅读@EnableScheduling的JavaDoc以获取更多信息。


更新

截至今年春季,Spring Jira问题SPR-10456已经解决。因此,@Scheduled注释具有新的zone属性,正是出于这个目的,例如:

@Scheduled(cron = "0 0 14 * * *", zone = "CET")
public void execute() {
    // do scheduled job
}

18
投票

注释zone中有元素@Scheduled,从4.0版开始。

您可以将时区插入java.util.TimeZone可以接受的字符串。


1
投票

你也可以在spring-boot中使用时区和@Scheduled标签,如下所示:

@Scheduled(cron = "0 0 14 * * *" , zone = "GMT+5:00")
public void execute() {
    // do the scheduled job
}

0
投票

我怀疑你想要不同的工作或部分应用程序使用不同的时区。假设您希望将所有服务器配置为具有一致的时区,或者为所有服务器设置user.timezone Java系统属性。集中管理配置(操作系统,应用程序服务器),对于那个木偶和厨师来说非常有用。


0
投票

你的代码应该是这样的:

@Scheduled(cron = "0 0 14 * * *", zone = "GMT-5")
    public void execute() {
     // do scheduled job
}

“Zone”将成为所需国家的时区。

这是关于Spring的计划任务的一个很好的教程:

https://www.baeldung.com/cron-expressions

© www.soinside.com 2019 - 2024. All rights reserved.