1. Introduction
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.
In this tutorial, we’ll look at various ways to conditionally enable Spring scheduled jobs.
2. Using a Boolean Flag
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:
@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.
3. Using @ConditionalOnProperty
Another option is to use the @ConditionalOnProperty annotation. It takes a Spring property name and runs only if the property evaluates to 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:
@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.
4. Using 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.
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:
@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.
One thing to be careful of with this approach is that the bean method will be executed if no profiles are specified at all.
5. Value Placeholder in Cron Expression
Using Spring value placeholders, not only can we conditionally enable a job, but we can also change its schedule:
@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).
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.
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.
6. Conclusion
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.
The full source code for the examples is available over on GitHub.