How can I disable the schedule auto-start on Spring Boot IntegrationTest?
Thanks.
Be aware that external components could be enabling scheduling automatically (see HystrixStreamAutoConfiguration and MetricExportAutoConfiguration from the Spring Framework). So if you try and use @ConditionalOnProperty
or @Profile
on the @Configuration
class that specifies @EnableScheduling
, then scheduling will be enabled anyway due to external components.
Have one @Configuration
class that enables scheduling via @EnableScheduling
, but then have your scheduled jobs in separate classes, each of those using @ConditionalOnProperty
to enable/disable the classes that contain the @Scheduled tasks.
Don't have the @Scheduled
and @EnableScheduling
in the same class, or you will have the issue where external components are enabling it anyway, so the @ConditionalOnProperty
is ignored.
Eg:
@Configuration
@EnableScheduling
public class MyApplicationSchedulingConfiguration {
}
and then in a separate class
@Named
@ConditionalOnProperty(value = "scheduling.enabled", havingValue = "true", matchIfMissing = false)
public class MyApplicationScheduledTasks {
@Scheduled(fixedRate = 60 * 60 * 1000)
public void runSomeTaskHourly() {
doStuff();
}
}
The issue with this solution is that every scheduled job needs to be in it's own class with @ConditionalOnProperty
specified. If you miss that annotation, then the job will run.
Extend the ThreadPoolTaskScheduler
and override the TaskScheduler
methods. In these methods you can perform a check to see if the job should run.
Then, in your @Configuration class where you use @EnableScheduling, you also create a @Bean called taskScheduler which returns your custom thread pool task scheduler).
Eg:
public class ConditionalThreadPoolTaskScheduler extends ThreadPoolTaskScheduler {
@Inject
private Environment environment;
// Override the TaskScheduler methods
@Override
public ScheduledFuture<?> schedule(Runnable task, Trigger trigger) {
if (!canRun()) {
return null;
}
return super.schedule(task, trigger);
}
@Override
public ScheduledFuture<?> schedule(Runnable task, Date startTime) {
if (!canRun()) {
return null;
}
return super.schedule(task, startTime);
}
@Override
public ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Date startTime, long period) {
if (!canRun()) {
return null;
}
return super.scheduleAtFixedRate(task, startTime, period);
}
@Override
public ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long period) {
if (!canRun()) {
return null;
}
return super.scheduleAtFixedRate(task, period);
}
@Override
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Date startTime, long delay) {
if (!canRun()) {
return null;
}
return super.scheduleWithFixedDelay(task, startTime, delay);
}
@Override
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, long delay) {
if (!canRun()) {
return null;
}
return super.scheduleWithFixedDelay(task, delay);
}
private boolean canRun() {
if (environment == null) {
return false;
}
if (!Boolean.valueOf(environment.getProperty("scheduling.enabled"))) {
return false;
}
return true;
}
}
Configuration class that creates the taskScheduler bean using our custom scheduler, and enables scheduling
@Configuration
@EnableScheduling
public class MyApplicationSchedulingConfiguration {
@Bean
public TaskScheduler taskScheduler() {
return new ConditionalThreadPoolTaskScheduler();
}
}
The potential issue with the above is that you've created a dependency on an internal Spring class, so if there are changes in the future, you'd have to fix compatibility.