Conditionally Enable Scheduled Jobs in Spring – 有条件地启用Spring中的计划工作

最后修改: 2019年 1月 29日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.绪论

The Spring Scheduling library allows applications to execute code at specific intervals. Because the intervals are specified using the @Scheduled annotation, the intervals are typically static and cannot change over the life of an application.

Spring Scheduling库允许应用程序以特定的时间间隔执行代码。由于使用@Scheduled注解来指定时间间隔,这些时间间隔通常是静态的,不能在应用程序的生命周期中改变

In this tutorial, we’ll look at various ways to conditionally enable Spring scheduled jobs.

在本教程中,我们将看看有条件地启用Spring计划作业的各种方法。

2. Using a Boolean Flag

2.使用一个布尔标志

The simplest way to conditionally enable a Spring scheduled job is to use a boolean variable that we check inside the scheduled job. The variable can be annotated with @Value to make it configurable using normal Spring configuration mechanisms:

有条件地启用Spring预定作业的最简单方法是使用一个boolean变量,我们在预定作业中检查该变量。该变量可以用@Value进行注释,以使其可使用正常的Spring配置机制进行配置。

@Configuration
@EnableScheduling
public class ScheduledJobs {
  @Value("${jobs.enabled:true}")
  private boolean isEnabled;

  @Scheduled(fixedDelay = 60000)
  public void cleanTempDirectory() {
    if(isEnabled) {
      // do work here
    }
  }
}

The downside is that the scheduled job will always be executed by Spring, which may not be ideal in some cases.

缺点是,计划中的工作将始终由Spring执行,这在某些情况下可能不是很理想。

3. Using @ConditionalOnProperty

3.使用@ConditionalOnProperty

Another option is to use the @ConditionalOnProperty annotation. It takes a Spring property name and runs only if the property evaluates to true.

另一个选择是使用@ConditionalOnProperty注解。它需要一个Spring属性名称,并且只在该属性评估为true时运行。

First, we create a new class that encapsulates the scheduled job code, including the schedule interval:

首先,我们创建一个新的类,它封装了计划工作的代码,包括计划时间间隔。

public class ScheduledJob {
    @Scheduled(fixedDelay = 60000)
    public void cleanTempDir() {
        // do work here
  }
}

Then we conditionally create a bean of that type:

然后我们有条件地创建一个该类型的bean。

@Configuration
@EnableScheduling
public class ScheduledJobs {
    @Bean
    @ConditionalOnProperty(value = "jobs.enabled", matchIfMissing = true, havingValue = "true")
    public ScheduledJob scheduledJob() {
        return new ScheduledJob();
    }
}

In this case, the job will run if the property jobs.enabled is set to true, or if it’s not present at all. The downside is that this annotation is available only in Spring Boot.

在这种情况下,如果属性jobs.enabled被设置为true,或者根本不存在,作业就会运行。缺点是,这个注解只在Spring Boot中可用

4. Using Spring Profiles

4.使用Spring Profiles

We can also conditionally enable a Spring scheduled job based on the profile that the application is running with. As an example, this approach is useful when a job should only be scheduled in the production environment.

我们还可以根据应用程序正在运行的配置文件,有条件地启用Spring调度的作业。举例来说,当一个作业只应在生产环境中进行调度时,这种方法就很有用。

This approach works well when the schedule is the same across all environments and it only needs to be disabled or enabled in specific profiles.

这种方法效果很好当时间表在所有环境中都是一样的,而且只需要在特定的配置文件中禁用或启用

This works similarly to using @ConditionalOnProperty, except we use the @Profile annotation on our bean method:

这与使用@ConditionalOnProperty的工作方式类似,只是我们在我们的bean方法上使用@Profile注解。

@Profile("prod")
@Bean
public ScheduledJob scheduledJob() {
    return new ScheduledJob();
}

This would create the job only if the prod profile is active. Furthermore, it gives us the full set of options that come with the @Profile annotation: matching multiple profiles, complex spring expressions, and more.

这将仅在prod配置文件处于活动状态时创建作业。此外,它为我们提供了@Profile注解所带来的全套选项:匹配多个配置文件、复杂的Spring表达式,等等。

One thing to be careful of with this approach is that the bean method will be executed if no profiles are specified at all.

这种方法需要注意的一点是,如果根本没有指定配置文件,bean方法将被执行

5. Value Placeholder in Cron Expression

5.Cron表达式中的值占位符

Using Spring value placeholders, not only can we conditionally enable a job, but we can also change its schedule:

使用Spring值占位符,我们不仅可以有条件地启用一个作业,而且还可以改变其时间表。

@Scheduled(cron = "${jobs.cronSchedule:-}")
public void cleanTempDirectory() {
    // do work here
}

In this example, the job is disabled by default (using the special Spring cron disable expression).

在这个例子中,该作业默认是禁用的(使用特殊的Spring cron disable表达式)。

If we want to enable the job, all we have to do is provide a valid cron expression for jobs.cronSchedule. We can do this just like any other Spring configuration: command-line argument, environment variable, property file, and so on.

如果我们想启用作业,我们所要做的就是为jobs.cronSchedule.提供一个有效的cron表达式。我们可以像其他Spring配置那样做:命令行参数、环境变量、属性文件等等。

Unlike cron expressions, there’s no way to set a fixed delay or fixed-rate value that disables a job. Therefore this approach only works with cron scheduled jobs.

与cron表达式不同,没有办法设置一个固定的延迟或固定的速率值来禁用一个作业。因此,这种方法只适用于cron计划的作业

6. Conclusion

6.结语

In this tutorial, we’ve seen there are several different ways to conditionally enable a Spring scheduled job. Some approaches are simpler than others but may have limitations.

在本教程中,我们已经看到有几种不同的方法来有条件地启用Spring计划作业。有些方法比其他方法更简单,但可能有局限性。

The full source code for the examples is available over on GitHub.

例子的完整源代码可在GitHub上获得over