Skip to content

Commit ffd6eff

Browse files
committed
Scheduled task introspection through ScheduledTaskHolder interface
Issue: SPR-15982
1 parent 9511d29 commit ffd6eff

File tree

12 files changed

+272
-37
lines changed

12 files changed

+272
-37
lines changed

spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,10 @@
6060
import org.springframework.scheduling.TaskScheduler;
6161
import org.springframework.scheduling.Trigger;
6262
import org.springframework.scheduling.config.CronTask;
63-
import org.springframework.scheduling.config.IntervalTask;
63+
import org.springframework.scheduling.config.FixedDelayTask;
64+
import org.springframework.scheduling.config.FixedRateTask;
6465
import org.springframework.scheduling.config.ScheduledTask;
66+
import org.springframework.scheduling.config.ScheduledTaskHolder;
6567
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
6668
import org.springframework.scheduling.support.CronTrigger;
6769
import org.springframework.scheduling.support.ScheduledMethodRunnable;
@@ -96,7 +98,7 @@
9698
* @see AsyncAnnotationBeanPostProcessor
9799
*/
98100
public class ScheduledAnnotationBeanPostProcessor
99-
implements MergedBeanDefinitionPostProcessor, DestructionAwareBeanPostProcessor,
101+
implements ScheduledTaskHolder, MergedBeanDefinitionPostProcessor, DestructionAwareBeanPostProcessor,
100102
Ordered, EmbeddedValueResolverAware, BeanNameAware, BeanFactoryAware, ApplicationContextAware,
101103
SmartInitializingSingleton, ApplicationListener<ContextRefreshedEvent>, DisposableBean {
102104

@@ -400,7 +402,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
400402
if (fixedDelay >= 0) {
401403
Assert.isTrue(!processedSchedule, errorMessage);
402404
processedSchedule = true;
403-
tasks.add(this.registrar.scheduleFixedDelayTask(new IntervalTask(runnable, fixedDelay, initialDelay)));
405+
tasks.add(this.registrar.scheduleFixedDelayTask(new FixedDelayTask(runnable, fixedDelay, initialDelay)));
404406
}
405407
String fixedDelayString = scheduled.fixedDelayString();
406408
if (StringUtils.hasText(fixedDelayString)) {
@@ -417,7 +419,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
417419
throw new IllegalArgumentException(
418420
"Invalid fixedDelayString value \"" + fixedDelayString + "\" - cannot parse into long");
419421
}
420-
tasks.add(this.registrar.scheduleFixedDelayTask(new IntervalTask(runnable, fixedDelay, initialDelay)));
422+
tasks.add(this.registrar.scheduleFixedDelayTask(new FixedDelayTask(runnable, fixedDelay, initialDelay)));
421423
}
422424
}
423425

@@ -426,7 +428,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
426428
if (fixedRate >= 0) {
427429
Assert.isTrue(!processedSchedule, errorMessage);
428430
processedSchedule = true;
429-
tasks.add(this.registrar.scheduleFixedRateTask(new IntervalTask(runnable, fixedRate, initialDelay)));
431+
tasks.add(this.registrar.scheduleFixedRateTask(new FixedRateTask(runnable, fixedRate, initialDelay)));
430432
}
431433
String fixedRateString = scheduled.fixedRateString();
432434
if (StringUtils.hasText(fixedRateString)) {
@@ -443,7 +445,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
443445
throw new IllegalArgumentException(
444446
"Invalid fixedRateString value \"" + fixedRateString + "\" - cannot parse into integer");
445447
}
446-
tasks.add(this.registrar.scheduleFixedRateTask(new IntervalTask(runnable, fixedRate, initialDelay)));
448+
tasks.add(this.registrar.scheduleFixedRateTask(new FixedRateTask(runnable, fixedRate, initialDelay)));
447449
}
448450
}
449451

@@ -467,6 +469,24 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
467469
}
468470

469471

472+
/**
473+
* Return all currently scheduled tasks, from {@link Scheduled} methods
474+
* as well as from programmatic {@link SchedulingConfigurer} interaction.
475+
* @since 5.0.2
476+
*/
477+
@Override
478+
public Set<ScheduledTask> getScheduledTasks() {
479+
Set<ScheduledTask> result = new LinkedHashSet<>();
480+
synchronized (this.scheduledTasks) {
481+
Collection<Set<ScheduledTask>> allTasks = this.scheduledTasks.values();
482+
for (Set<ScheduledTask> tasks : allTasks) {
483+
result.addAll(tasks);
484+
}
485+
}
486+
result.addAll(this.registrar.getScheduledTasks());
487+
return result;
488+
}
489+
470490
@Override
471491
public void postProcessBeforeDestruction(Object bean, String beanName) {
472492
Set<ScheduledTask> tasks;

spring-context/src/main/java/org/springframework/scheduling/config/CronTask.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -26,8 +26,7 @@
2626
* @author Chris Beams
2727
* @since 3.2
2828
* @see org.springframework.scheduling.annotation.Scheduled#cron()
29-
* @see ScheduledTaskRegistrar#setCronTasksList(java.util.List)
30-
* @see org.springframework.scheduling.TaskScheduler
29+
* @see ScheduledTaskRegistrar#addCronTask(CronTask)
3130
*/
3231
public class CronTask extends TriggerTask {
3332

@@ -37,7 +36,7 @@ public class CronTask extends TriggerTask {
3736
/**
3837
* Create a new {@code CronTask}.
3938
* @param runnable the underlying task to execute
40-
* @param expression cron expression defining when the task should be executed
39+
* @param expression the cron expression defining when the task should be executed
4140
*/
4241
public CronTask(Runnable runnable, String expression) {
4342
this(runnable, new CronTrigger(expression));
@@ -54,6 +53,9 @@ public CronTask(Runnable runnable, CronTrigger cronTrigger) {
5453
}
5554

5655

56+
/**
57+
* Return the cron expression defining when the task should be executed.
58+
*/
5759
public String getExpression() {
5860
return this.expression;
5961
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2002-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.scheduling.config;
18+
19+
/**
20+
* Specialization of {@link IntervalTask} for fixed-delay semantics.
21+
*
22+
* @author Juergen Hoeller
23+
* @since 5.0.2
24+
* @see org.springframework.scheduling.annotation.Scheduled#fixedDelay()
25+
* @see ScheduledTaskRegistrar#addFixedDelayTask(IntervalTask)
26+
*/
27+
public class FixedDelayTask extends IntervalTask {
28+
29+
/**
30+
* Create a new {@code FixedDelayTask}.
31+
* @param runnable the underlying task to execute
32+
* @param interval how often in milliseconds the task should be executed
33+
* @param initialDelay the initial delay before first execution of the task
34+
*/
35+
public FixedDelayTask(Runnable runnable, long interval, long initialDelay) {
36+
super(runnable, interval, initialDelay);
37+
}
38+
39+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2002-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.scheduling.config;
18+
19+
/**
20+
* Specialization of {@link IntervalTask} for fixed-rate semantics.
21+
*
22+
* @author Juergen Hoeller
23+
* @since 5.0.2
24+
* @see org.springframework.scheduling.annotation.Scheduled#fixedRate()
25+
* @see ScheduledTaskRegistrar#addFixedRateTask(IntervalTask)
26+
*/
27+
public class FixedRateTask extends IntervalTask {
28+
29+
/**
30+
* Create a new {@code FixedRateTask}.
31+
* @param runnable the underlying task to execute
32+
* @param interval how often in milliseconds the task should be executed
33+
* @param initialDelay the initial delay before first execution of the task
34+
*/
35+
public FixedRateTask(Runnable runnable, long interval, long initialDelay) {
36+
super(runnable, interval, initialDelay);
37+
}
38+
39+
}

spring-context/src/main/java/org/springframework/scheduling/config/IntervalTask.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,11 +23,8 @@
2323
*
2424
* @author Chris Beams
2525
* @since 3.2
26-
* @see org.springframework.scheduling.annotation.Scheduled#fixedRate()
27-
* @see org.springframework.scheduling.annotation.Scheduled#fixedDelay()
28-
* @see ScheduledTaskRegistrar#setFixedRateTasksList(java.util.List)
29-
* @see ScheduledTaskRegistrar#setFixedDelayTasksList(java.util.List)
30-
* @see org.springframework.scheduling.TaskScheduler
26+
* @see ScheduledTaskRegistrar#addFixedRateTask(IntervalTask)
27+
* @see ScheduledTaskRegistrar#addFixedDelayTask(IntervalTask)
3128
*/
3229
public class IntervalTask extends Task {
3330

@@ -40,7 +37,7 @@ public class IntervalTask extends Task {
4037
* Create a new {@code IntervalTask}.
4138
* @param runnable the underlying task to execute
4239
* @param interval how often in milliseconds the task should be executed
43-
* @param initialDelay initial delay before first execution of the task
40+
* @param initialDelay the initial delay before first execution of the task
4441
*/
4542
public IntervalTask(Runnable runnable, long interval, long initialDelay) {
4643
super(runnable);
@@ -58,10 +55,16 @@ public IntervalTask(Runnable runnable, long interval) {
5855
}
5956

6057

58+
/**
59+
* Return how often in milliseconds the task should be executed.
60+
*/
6161
public long getInterval() {
6262
return this.interval;
6363
}
6464

65+
/**
66+
* Return the initial delay before first execution of the task.
67+
*/
6568
public long getInitialDelay() {
6669
return this.initialDelay;
6770
}

spring-context/src/main/java/org/springframework/scheduling/config/ScheduledTask.java

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,37 @@
2121
import org.springframework.lang.Nullable;
2222

2323
/**
24-
* A representation of a scheduled task,
24+
* A representation of a scheduled task at runtime,
2525
* used as a return value for scheduling methods.
2626
*
2727
* @author Juergen Hoeller
2828
* @since 4.3
29-
* @see ScheduledTaskRegistrar#scheduleTriggerTask
30-
* @see ScheduledTaskRegistrar#scheduleFixedRateTask
29+
* @see ScheduledTaskRegistrar#scheduleCronTask(CronTask)
30+
* @see ScheduledTaskRegistrar#scheduleFixedRateTask(FixedRateTask)
31+
* @see ScheduledTaskRegistrar#scheduleFixedDelayTask(FixedDelayTask)
3132
*/
3233
public final class ScheduledTask {
3334

35+
private final Task task;
36+
3437
@Nullable
3538
volatile ScheduledFuture<?> future;
3639

3740

38-
ScheduledTask() {
41+
ScheduledTask(Task task) {
42+
this.task = task;
3943
}
4044

4145

46+
/**
47+
* Return the underlying task (typically a {@link CronTask},
48+
* {@link FixedRateTask} or {@link FixedDelayTask}).
49+
* @since 5.0.2
50+
*/
51+
public Task getTask() {
52+
return this.task;
53+
}
54+
4255
/**
4356
* Trigger cancellation of this scheduled task.
4457
*/
@@ -49,4 +62,9 @@ public void cancel() {
4962
}
5063
}
5164

65+
@Override
66+
public String toString() {
67+
return this.task.toString();
68+
}
69+
5270
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2002-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.scheduling.config;
18+
19+
import java.util.Set;
20+
21+
/**
22+
* Common interface for exposing locally scheduled tasks.
23+
*
24+
* @author Juergen Hoeller
25+
* @since 5.0.2
26+
* @see ScheduledTaskRegistrar
27+
* @see org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor
28+
*/
29+
public interface ScheduledTaskHolder {
30+
31+
/**
32+
* Return an overview of the tasks that have been scheduled by this instance.
33+
*/
34+
Set<ScheduledTask> getScheduledTasks();
35+
36+
}

0 commit comments

Comments
 (0)