Support disabling cron jobs registered via SchedulingConfigurer
Prior to this commit, support was provided for disabling cron jobs configured with an explicit "-" cron expression. However, the "-" expression was only supported when supplied via the @Scheduled annotation. This commit adds support for disabling cron jobs configured with the "-" cron expression when a cron job is registered via the addCronTask(Runnable, String) method in the ScheduledTaskRegistrar supplied to a SchedulingConfigurer. Closes gh-23568
This commit is contained in:
parent
fc6480631e
commit
d689ef8891
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2018 the original author or authors.
|
* Copyright 2002-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -42,20 +42,33 @@ import org.springframework.util.CollectionUtils;
|
||||||
* expressions.
|
* expressions.
|
||||||
*
|
*
|
||||||
* <p>As of Spring 3.1, {@code ScheduledTaskRegistrar} has a more prominent user-facing
|
* <p>As of Spring 3.1, {@code ScheduledTaskRegistrar} has a more prominent user-facing
|
||||||
* role when used in conjunction with the @{@link
|
* role when used in conjunction with the {@link
|
||||||
* org.springframework.scheduling.annotation.EnableAsync EnableAsync} annotation and its
|
* org.springframework.scheduling.annotation.EnableAsync @EnableAsync} annotation and its
|
||||||
* {@link org.springframework.scheduling.annotation.SchedulingConfigurer
|
* {@link org.springframework.scheduling.annotation.SchedulingConfigurer
|
||||||
* SchedulingConfigurer} callback interface.
|
* SchedulingConfigurer} callback interface.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Chris Beams
|
* @author Chris Beams
|
||||||
* @author Tobias Montagna-Hay
|
* @author Tobias Montagna-Hay
|
||||||
|
* @author Sam Brannen
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see org.springframework.scheduling.annotation.EnableAsync
|
* @see org.springframework.scheduling.annotation.EnableAsync
|
||||||
* @see org.springframework.scheduling.annotation.SchedulingConfigurer
|
* @see org.springframework.scheduling.annotation.SchedulingConfigurer
|
||||||
*/
|
*/
|
||||||
public class ScheduledTaskRegistrar implements ScheduledTaskHolder, InitializingBean, DisposableBean {
|
public class ScheduledTaskRegistrar implements ScheduledTaskHolder, InitializingBean, DisposableBean {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A special cron expression value that indicates a disabled trigger: {@value}.
|
||||||
|
* <p>This is primarily meant for use with {@link #addCronTask(Runnable, String)}
|
||||||
|
* when the value for the supplied {@code expression} is retrieved from an
|
||||||
|
* external source — for example, from a property in the
|
||||||
|
* {@link org.springframework.core.env.Environment Environment}.
|
||||||
|
* @since 5.2
|
||||||
|
* @see org.springframework.scheduling.annotation.Scheduled#CRON_DISABLED
|
||||||
|
*/
|
||||||
|
public static final String CRON_DISABLED = "-";
|
||||||
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private TaskScheduler taskScheduler;
|
private TaskScheduler taskScheduler;
|
||||||
|
|
||||||
|
@ -254,11 +267,15 @@ public class ScheduledTaskRegistrar implements ScheduledTaskHolder, Initializing
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a Runnable task to be triggered per the given cron expression.
|
* Add a {@link Runnable} task to be triggered per the given cron {@code expression}.
|
||||||
|
* <p>As of Spring Framework 5.2, this method will not register the task if the
|
||||||
|
* {@code expression} is equal to {@link #CRON_DISABLED}.
|
||||||
*/
|
*/
|
||||||
public void addCronTask(Runnable task, String expression) {
|
public void addCronTask(Runnable task, String expression) {
|
||||||
|
if (!CRON_DISABLED.equals(expression)) {
|
||||||
addCronTask(new CronTask(task, expression));
|
addCronTask(new CronTask(task, expression));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a {@link CronTask}.
|
* Add a {@link CronTask}.
|
||||||
|
|
|
@ -17,11 +17,12 @@
|
||||||
package org.springframework.scheduling.config;
|
package org.springframework.scheduling.config;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -29,59 +30,69 @@ import static org.mockito.Mockito.mock;
|
||||||
*
|
*
|
||||||
* @author Tobias Montagna-Hay
|
* @author Tobias Montagna-Hay
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
|
* @author Sam Brannen
|
||||||
* @since 4.2
|
* @since 4.2
|
||||||
*/
|
*/
|
||||||
public class ScheduledTaskRegistrarTests {
|
class ScheduledTaskRegistrarTests {
|
||||||
|
|
||||||
|
private static final Runnable no_op = () -> {};
|
||||||
|
|
||||||
private final ScheduledTaskRegistrar taskRegistrar = new ScheduledTaskRegistrar();
|
private final ScheduledTaskRegistrar taskRegistrar = new ScheduledTaskRegistrar();
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@BeforeEach
|
||||||
public void emptyTaskLists() {
|
void preconditions() {
|
||||||
assertThat(this.taskRegistrar.getTriggerTaskList().isEmpty()).isTrue();
|
assertThat(this.taskRegistrar.getTriggerTaskList()).isEmpty();
|
||||||
assertThat(this.taskRegistrar.getCronTaskList().isEmpty()).isTrue();
|
assertThat(this.taskRegistrar.getCronTaskList()).isEmpty();
|
||||||
assertThat(this.taskRegistrar.getFixedRateTaskList().isEmpty()).isTrue();
|
assertThat(this.taskRegistrar.getFixedRateTaskList()).isEmpty();
|
||||||
assertThat(this.taskRegistrar.getFixedDelayTaskList().isEmpty()).isTrue();
|
assertThat(this.taskRegistrar.getFixedDelayTaskList()).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getTriggerTasks() {
|
void getTriggerTasks() {
|
||||||
TriggerTask mockTriggerTask = mock(TriggerTask.class);
|
TriggerTask mockTriggerTask = mock(TriggerTask.class);
|
||||||
List<TriggerTask> triggerTaskList = Collections.singletonList(mockTriggerTask);
|
this.taskRegistrar.setTriggerTasksList(Collections.singletonList(mockTriggerTask));
|
||||||
this.taskRegistrar.setTriggerTasksList(triggerTaskList);
|
assertThat(this.taskRegistrar.getTriggerTaskList()).containsExactly(mockTriggerTask);
|
||||||
List<TriggerTask> retrievedList = this.taskRegistrar.getTriggerTaskList();
|
|
||||||
assertThat(retrievedList.size()).isEqualTo(1);
|
|
||||||
assertThat(retrievedList.get(0)).isEqualTo(mockTriggerTask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getCronTasks() {
|
void getCronTasks() {
|
||||||
CronTask mockCronTask = mock(CronTask.class);
|
CronTask mockCronTask = mock(CronTask.class);
|
||||||
List<CronTask> cronTaskList = Collections.singletonList(mockCronTask);
|
this.taskRegistrar.setCronTasksList(Collections.singletonList(mockCronTask));
|
||||||
this.taskRegistrar.setCronTasksList(cronTaskList);
|
assertThat(this.taskRegistrar.getCronTaskList()).containsExactly(mockCronTask);
|
||||||
List<CronTask> retrievedList = this.taskRegistrar.getCronTaskList();
|
|
||||||
assertThat(retrievedList.size()).isEqualTo(1);
|
|
||||||
assertThat(retrievedList.get(0)).isEqualTo(mockCronTask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getFixedRateTasks() {
|
void getFixedRateTasks() {
|
||||||
IntervalTask mockFixedRateTask = mock(IntervalTask.class);
|
IntervalTask mockFixedRateTask = mock(IntervalTask.class);
|
||||||
List<IntervalTask> fixedRateTaskList = Collections.singletonList(mockFixedRateTask);
|
this.taskRegistrar.setFixedRateTasksList(Collections.singletonList(mockFixedRateTask));
|
||||||
this.taskRegistrar.setFixedRateTasksList(fixedRateTaskList);
|
assertThat(this.taskRegistrar.getFixedRateTaskList()).containsExactly(mockFixedRateTask);
|
||||||
List<IntervalTask> retrievedList = this.taskRegistrar.getFixedRateTaskList();
|
|
||||||
assertThat(retrievedList.size()).isEqualTo(1);
|
|
||||||
assertThat(retrievedList.get(0)).isEqualTo(mockFixedRateTask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getFixedDelayTasks() {
|
void getFixedDelayTasks() {
|
||||||
IntervalTask mockFixedDelayTask = mock(IntervalTask.class);
|
IntervalTask mockFixedDelayTask = mock(IntervalTask.class);
|
||||||
List<IntervalTask> fixedDelayTaskList = Collections.singletonList(mockFixedDelayTask);
|
this.taskRegistrar.setFixedDelayTasksList(Collections.singletonList(mockFixedDelayTask));
|
||||||
this.taskRegistrar.setFixedDelayTasksList(fixedDelayTaskList);
|
assertThat(this.taskRegistrar.getFixedDelayTaskList()).containsExactly(mockFixedDelayTask);
|
||||||
List<IntervalTask> retrievedList = this.taskRegistrar.getFixedDelayTaskList();
|
}
|
||||||
assertThat(retrievedList.size()).isEqualTo(1);
|
|
||||||
assertThat(retrievedList.get(0)).isEqualTo(mockFixedDelayTask);
|
@Test
|
||||||
|
void addCronTaskWithValidExpression() {
|
||||||
|
this.taskRegistrar.addCronTask(no_op, "* * * * * ?");
|
||||||
|
assertThat(this.taskRegistrar.getCronTaskList()).size().isEqualTo(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void addCronTaskWithInvalidExpression() {
|
||||||
|
assertThatIllegalArgumentException()
|
||||||
|
.isThrownBy(() -> this.taskRegistrar.addCronTask(no_op, "* * *"))
|
||||||
|
.withMessage("Cron expression must consist of 6 fields (found 3 in \"* * *\")");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void addCronTaskWithDisabledExpression() {
|
||||||
|
this.taskRegistrar.addCronTask(no_op, ScheduledTaskRegistrar.CRON_DISABLED);
|
||||||
|
assertThat(this.taskRegistrar.getCronTaskList()).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue