From ffd6eff369014f49102bacaa84c0826235c01ee5 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 6 Nov 2017 18:36:39 +0100 Subject: [PATCH] Scheduled task introspection through ScheduledTaskHolder interface Issue: SPR-15982 --- .../ScheduledAnnotationBeanPostProcessor.java | 32 ++++++++-- .../scheduling/config/CronTask.java | 10 ++-- .../scheduling/config/FixedDelayTask.java | 39 ++++++++++++ .../scheduling/config/FixedRateTask.java | 39 ++++++++++++ .../scheduling/config/IntervalTask.java | 17 +++--- .../scheduling/config/ScheduledTask.java | 26 ++++++-- .../config/ScheduledTaskHolder.java | 36 +++++++++++ .../config/ScheduledTaskRegistrar.java | 59 ++++++++++++++++--- .../scheduling/config/Task.java | 20 ++++++- .../scheduling/config/TriggerTask.java | 10 +++- .../support/ScheduledMethodRunnable.java | 7 ++- .../annotation/EnableSchedulingTests.java | 14 ++++- 12 files changed, 272 insertions(+), 37 deletions(-) create mode 100644 spring-context/src/main/java/org/springframework/scheduling/config/FixedDelayTask.java create mode 100644 spring-context/src/main/java/org/springframework/scheduling/config/FixedRateTask.java create mode 100644 spring-context/src/main/java/org/springframework/scheduling/config/ScheduledTaskHolder.java diff --git a/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java index f4d96363df..05c9c3d089 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java @@ -60,8 +60,10 @@ import org.springframework.lang.Nullable; import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.Trigger; import org.springframework.scheduling.config.CronTask; -import org.springframework.scheduling.config.IntervalTask; +import org.springframework.scheduling.config.FixedDelayTask; +import org.springframework.scheduling.config.FixedRateTask; import org.springframework.scheduling.config.ScheduledTask; +import org.springframework.scheduling.config.ScheduledTaskHolder; import org.springframework.scheduling.config.ScheduledTaskRegistrar; import org.springframework.scheduling.support.CronTrigger; import org.springframework.scheduling.support.ScheduledMethodRunnable; @@ -96,7 +98,7 @@ import org.springframework.util.StringValueResolver; * @see AsyncAnnotationBeanPostProcessor */ public class ScheduledAnnotationBeanPostProcessor - implements MergedBeanDefinitionPostProcessor, DestructionAwareBeanPostProcessor, + implements ScheduledTaskHolder, MergedBeanDefinitionPostProcessor, DestructionAwareBeanPostProcessor, Ordered, EmbeddedValueResolverAware, BeanNameAware, BeanFactoryAware, ApplicationContextAware, SmartInitializingSingleton, ApplicationListener, DisposableBean { @@ -400,7 +402,7 @@ public class ScheduledAnnotationBeanPostProcessor if (fixedDelay >= 0) { Assert.isTrue(!processedSchedule, errorMessage); processedSchedule = true; - tasks.add(this.registrar.scheduleFixedDelayTask(new IntervalTask(runnable, fixedDelay, initialDelay))); + tasks.add(this.registrar.scheduleFixedDelayTask(new FixedDelayTask(runnable, fixedDelay, initialDelay))); } String fixedDelayString = scheduled.fixedDelayString(); if (StringUtils.hasText(fixedDelayString)) { @@ -417,7 +419,7 @@ public class ScheduledAnnotationBeanPostProcessor throw new IllegalArgumentException( "Invalid fixedDelayString value \"" + fixedDelayString + "\" - cannot parse into long"); } - tasks.add(this.registrar.scheduleFixedDelayTask(new IntervalTask(runnable, fixedDelay, initialDelay))); + tasks.add(this.registrar.scheduleFixedDelayTask(new FixedDelayTask(runnable, fixedDelay, initialDelay))); } } @@ -426,7 +428,7 @@ public class ScheduledAnnotationBeanPostProcessor if (fixedRate >= 0) { Assert.isTrue(!processedSchedule, errorMessage); processedSchedule = true; - tasks.add(this.registrar.scheduleFixedRateTask(new IntervalTask(runnable, fixedRate, initialDelay))); + tasks.add(this.registrar.scheduleFixedRateTask(new FixedRateTask(runnable, fixedRate, initialDelay))); } String fixedRateString = scheduled.fixedRateString(); if (StringUtils.hasText(fixedRateString)) { @@ -443,7 +445,7 @@ public class ScheduledAnnotationBeanPostProcessor throw new IllegalArgumentException( "Invalid fixedRateString value \"" + fixedRateString + "\" - cannot parse into integer"); } - tasks.add(this.registrar.scheduleFixedRateTask(new IntervalTask(runnable, fixedRate, initialDelay))); + tasks.add(this.registrar.scheduleFixedRateTask(new FixedRateTask(runnable, fixedRate, initialDelay))); } } @@ -467,6 +469,24 @@ public class ScheduledAnnotationBeanPostProcessor } + /** + * Return all currently scheduled tasks, from {@link Scheduled} methods + * as well as from programmatic {@link SchedulingConfigurer} interaction. + * @since 5.0.2 + */ + @Override + public Set getScheduledTasks() { + Set result = new LinkedHashSet<>(); + synchronized (this.scheduledTasks) { + Collection> allTasks = this.scheduledTasks.values(); + for (Set tasks : allTasks) { + result.addAll(tasks); + } + } + result.addAll(this.registrar.getScheduledTasks()); + return result; + } + @Override public void postProcessBeforeDestruction(Object bean, String beanName) { Set tasks; diff --git a/spring-context/src/main/java/org/springframework/scheduling/config/CronTask.java b/spring-context/src/main/java/org/springframework/scheduling/config/CronTask.java index b00b48060e..1050b7789e 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/config/CronTask.java +++ b/spring-context/src/main/java/org/springframework/scheduling/config/CronTask.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,8 +26,7 @@ import org.springframework.scheduling.support.CronTrigger; * @author Chris Beams * @since 3.2 * @see org.springframework.scheduling.annotation.Scheduled#cron() - * @see ScheduledTaskRegistrar#setCronTasksList(java.util.List) - * @see org.springframework.scheduling.TaskScheduler + * @see ScheduledTaskRegistrar#addCronTask(CronTask) */ public class CronTask extends TriggerTask { @@ -37,7 +36,7 @@ public class CronTask extends TriggerTask { /** * Create a new {@code CronTask}. * @param runnable the underlying task to execute - * @param expression cron expression defining when the task should be executed + * @param expression the cron expression defining when the task should be executed */ public CronTask(Runnable runnable, String expression) { this(runnable, new CronTrigger(expression)); @@ -54,6 +53,9 @@ public class CronTask extends TriggerTask { } + /** + * Return the cron expression defining when the task should be executed. + */ public String getExpression() { return this.expression; } diff --git a/spring-context/src/main/java/org/springframework/scheduling/config/FixedDelayTask.java b/spring-context/src/main/java/org/springframework/scheduling/config/FixedDelayTask.java new file mode 100644 index 0000000000..7959ab387d --- /dev/null +++ b/spring-context/src/main/java/org/springframework/scheduling/config/FixedDelayTask.java @@ -0,0 +1,39 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling.config; + +/** + * Specialization of {@link IntervalTask} for fixed-delay semantics. + * + * @author Juergen Hoeller + * @since 5.0.2 + * @see org.springframework.scheduling.annotation.Scheduled#fixedDelay() + * @see ScheduledTaskRegistrar#addFixedDelayTask(IntervalTask) + */ +public class FixedDelayTask extends IntervalTask { + + /** + * Create a new {@code FixedDelayTask}. + * @param runnable the underlying task to execute + * @param interval how often in milliseconds the task should be executed + * @param initialDelay the initial delay before first execution of the task + */ + public FixedDelayTask(Runnable runnable, long interval, long initialDelay) { + super(runnable, interval, initialDelay); + } + +} diff --git a/spring-context/src/main/java/org/springframework/scheduling/config/FixedRateTask.java b/spring-context/src/main/java/org/springframework/scheduling/config/FixedRateTask.java new file mode 100644 index 0000000000..6da91b95ef --- /dev/null +++ b/spring-context/src/main/java/org/springframework/scheduling/config/FixedRateTask.java @@ -0,0 +1,39 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling.config; + +/** + * Specialization of {@link IntervalTask} for fixed-rate semantics. + * + * @author Juergen Hoeller + * @since 5.0.2 + * @see org.springframework.scheduling.annotation.Scheduled#fixedRate() + * @see ScheduledTaskRegistrar#addFixedRateTask(IntervalTask) + */ +public class FixedRateTask extends IntervalTask { + + /** + * Create a new {@code FixedRateTask}. + * @param runnable the underlying task to execute + * @param interval how often in milliseconds the task should be executed + * @param initialDelay the initial delay before first execution of the task + */ + public FixedRateTask(Runnable runnable, long interval, long initialDelay) { + super(runnable, interval, initialDelay); + } + +} diff --git a/spring-context/src/main/java/org/springframework/scheduling/config/IntervalTask.java b/spring-context/src/main/java/org/springframework/scheduling/config/IntervalTask.java index 567f9fdbfe..3dbb82fa7e 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/config/IntervalTask.java +++ b/spring-context/src/main/java/org/springframework/scheduling/config/IntervalTask.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,11 +23,8 @@ package org.springframework.scheduling.config; * * @author Chris Beams * @since 3.2 - * @see org.springframework.scheduling.annotation.Scheduled#fixedRate() - * @see org.springframework.scheduling.annotation.Scheduled#fixedDelay() - * @see ScheduledTaskRegistrar#setFixedRateTasksList(java.util.List) - * @see ScheduledTaskRegistrar#setFixedDelayTasksList(java.util.List) - * @see org.springframework.scheduling.TaskScheduler + * @see ScheduledTaskRegistrar#addFixedRateTask(IntervalTask) + * @see ScheduledTaskRegistrar#addFixedDelayTask(IntervalTask) */ public class IntervalTask extends Task { @@ -40,7 +37,7 @@ public class IntervalTask extends Task { * Create a new {@code IntervalTask}. * @param runnable the underlying task to execute * @param interval how often in milliseconds the task should be executed - * @param initialDelay initial delay before first execution of the task + * @param initialDelay the initial delay before first execution of the task */ public IntervalTask(Runnable runnable, long interval, long initialDelay) { super(runnable); @@ -58,10 +55,16 @@ public class IntervalTask extends Task { } + /** + * Return how often in milliseconds the task should be executed. + */ public long getInterval() { return this.interval; } + /** + * Return the initial delay before first execution of the task. + */ public long getInitialDelay() { return this.initialDelay; } diff --git a/spring-context/src/main/java/org/springframework/scheduling/config/ScheduledTask.java b/spring-context/src/main/java/org/springframework/scheduling/config/ScheduledTask.java index 45e87ad282..f5fd4d55f8 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/config/ScheduledTask.java +++ b/spring-context/src/main/java/org/springframework/scheduling/config/ScheduledTask.java @@ -21,24 +21,37 @@ import java.util.concurrent.ScheduledFuture; import org.springframework.lang.Nullable; /** - * A representation of a scheduled task, + * A representation of a scheduled task at runtime, * used as a return value for scheduling methods. * * @author Juergen Hoeller * @since 4.3 - * @see ScheduledTaskRegistrar#scheduleTriggerTask - * @see ScheduledTaskRegistrar#scheduleFixedRateTask + * @see ScheduledTaskRegistrar#scheduleCronTask(CronTask) + * @see ScheduledTaskRegistrar#scheduleFixedRateTask(FixedRateTask) + * @see ScheduledTaskRegistrar#scheduleFixedDelayTask(FixedDelayTask) */ public final class ScheduledTask { + private final Task task; + @Nullable volatile ScheduledFuture future; - ScheduledTask() { + ScheduledTask(Task task) { + this.task = task; } + /** + * Return the underlying task (typically a {@link CronTask}, + * {@link FixedRateTask} or {@link FixedDelayTask}). + * @since 5.0.2 + */ + public Task getTask() { + return this.task; + } + /** * Trigger cancellation of this scheduled task. */ @@ -49,4 +62,9 @@ public final class ScheduledTask { } } + @Override + public String toString() { + return this.task.toString(); + } + } diff --git a/spring-context/src/main/java/org/springframework/scheduling/config/ScheduledTaskHolder.java b/spring-context/src/main/java/org/springframework/scheduling/config/ScheduledTaskHolder.java new file mode 100644 index 0000000000..fc32be87db --- /dev/null +++ b/spring-context/src/main/java/org/springframework/scheduling/config/ScheduledTaskHolder.java @@ -0,0 +1,36 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.scheduling.config; + +import java.util.Set; + +/** + * Common interface for exposing locally scheduled tasks. + * + * @author Juergen Hoeller + * @since 5.0.2 + * @see ScheduledTaskRegistrar + * @see org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor + */ +public interface ScheduledTaskHolder { + + /** + * Return an overview of the tasks that have been scheduled by this instance. + */ + Set getScheduledTasks(); + +} diff --git a/spring-context/src/main/java/org/springframework/scheduling/config/ScheduledTaskRegistrar.java b/spring-context/src/main/java/org/springframework/scheduling/config/ScheduledTaskRegistrar.java index 2dc2e5380c..a9928ad78a 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/config/ScheduledTaskRegistrar.java +++ b/spring-context/src/main/java/org/springframework/scheduling/config/ScheduledTaskRegistrar.java @@ -54,7 +54,7 @@ import org.springframework.util.CollectionUtils; * @see org.springframework.scheduling.annotation.EnableAsync * @see org.springframework.scheduling.annotation.SchedulingConfigurer */ -public class ScheduledTaskRegistrar implements InitializingBean, DisposableBean { +public class ScheduledTaskRegistrar implements ScheduledTaskHolder, InitializingBean, DisposableBean { @Nullable private TaskScheduler taskScheduler; @@ -333,8 +333,8 @@ public class ScheduledTaskRegistrar implements InitializingBean, DisposableBean } /** - * Schedule all registered tasks against the underlying {@linkplain - * #setTaskScheduler(TaskScheduler) task scheduler}. + * Schedule all registered tasks against the underlying + * {@linkplain #setTaskScheduler(TaskScheduler) task scheduler}. */ protected void scheduleTasks() { if (this.taskScheduler == null) { @@ -381,7 +381,7 @@ public class ScheduledTaskRegistrar implements InitializingBean, DisposableBean ScheduledTask scheduledTask = this.unresolvedTasks.remove(task); boolean newTask = false; if (scheduledTask == null) { - scheduledTask = new ScheduledTask(); + scheduledTask = new ScheduledTask(task); newTask = true; } if (this.taskScheduler != null) { @@ -406,7 +406,7 @@ public class ScheduledTaskRegistrar implements InitializingBean, DisposableBean ScheduledTask scheduledTask = this.unresolvedTasks.remove(task); boolean newTask = false; if (scheduledTask == null) { - scheduledTask = new ScheduledTask(); + scheduledTask = new ScheduledTask(task); newTask = true; } if (this.taskScheduler != null) { @@ -425,13 +425,29 @@ public class ScheduledTaskRegistrar implements InitializingBean, DisposableBean * @return a handle to the scheduled task, allowing to cancel it * (or {@code null} if processing a previously registered task) * @since 4.3 + * @deprecated as of 5.0.2, in favor of {@link #scheduleFixedRateTask(FixedRateTask)} */ + @Deprecated @Nullable public ScheduledTask scheduleFixedRateTask(IntervalTask task) { + FixedRateTask taskToUse = (task instanceof FixedRateTask ? (FixedRateTask) task : + new FixedRateTask(task.getRunnable(), task.getInterval(), task.getInitialDelay())); + return scheduleFixedRateTask(taskToUse); + } + + /** + * Schedule the specified fixed-rate task, either right away if possible + * or on initialization of the scheduler. + * @return a handle to the scheduled task, allowing to cancel it + * (or {@code null} if processing a previously registered task) + * @since 5.0.2 + */ + @Nullable + public ScheduledTask scheduleFixedRateTask(FixedRateTask task) { ScheduledTask scheduledTask = this.unresolvedTasks.remove(task); boolean newTask = false; if (scheduledTask == null) { - scheduledTask = new ScheduledTask(); + scheduledTask = new ScheduledTask(task); newTask = true; } if (this.taskScheduler != null) { @@ -458,13 +474,29 @@ public class ScheduledTaskRegistrar implements InitializingBean, DisposableBean * @return a handle to the scheduled task, allowing to cancel it * (or {@code null} if processing a previously registered task) * @since 4.3 + * @deprecated as of 5.0.2, in favor of {@link #scheduleFixedDelayTask(FixedDelayTask)} */ + @Deprecated @Nullable public ScheduledTask scheduleFixedDelayTask(IntervalTask task) { + FixedDelayTask taskToUse = (task instanceof FixedDelayTask ? (FixedDelayTask) task : + new FixedDelayTask(task.getRunnable(), task.getInterval(), task.getInitialDelay())); + return scheduleFixedDelayTask(taskToUse); + } + + /** + * Schedule the specified fixed-delay task, either right away if possible + * or on initialization of the scheduler. + * @return a handle to the scheduled task, allowing to cancel it + * (or {@code null} if processing a previously registered task) + * @since 5.0.2 + */ + @Nullable + public ScheduledTask scheduleFixedDelayTask(FixedDelayTask task) { ScheduledTask scheduledTask = this.unresolvedTasks.remove(task); boolean newTask = false; if (scheduledTask == null) { - scheduledTask = new ScheduledTask(); + scheduledTask = new ScheduledTask(task); newTask = true; } if (this.taskScheduler != null) { @@ -486,6 +518,19 @@ public class ScheduledTaskRegistrar implements InitializingBean, DisposableBean } + /** + * Return all locally registered tasks that have been scheduled by this registrar. + * @since 5.0.2 + * @see #addTriggerTask + * @see #addCronTask + * @see #addFixedRateTask + * @see #addFixedDelayTask + */ + @Override + public Set getScheduledTasks() { + return Collections.unmodifiableSet(this.scheduledTasks); + } + @Override public void destroy() { for (ScheduledTask task : this.scheduledTasks) { diff --git a/spring-context/src/main/java/org/springframework/scheduling/config/Task.java b/spring-context/src/main/java/org/springframework/scheduling/config/Task.java index 02dac4cba4..c107fe4c4f 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/config/Task.java +++ b/spring-context/src/main/java/org/springframework/scheduling/config/Task.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,14 @@ package org.springframework.scheduling.config; +import org.springframework.util.Assert; + /** * Holder class defining a {@code Runnable} to be executed as a task, typically at a * scheduled time or interval. See subclass hierarchy for various scheduling approaches. * * @author Chris Beams + * @author Juergen Hoeller * @since 3.2 */ public class Task { @@ -30,14 +33,25 @@ public class Task { /** * Create a new {@code Task}. - * @param runnable the underlying task to execute. + * @param runnable the underlying task to execute */ public Task(Runnable runnable) { + Assert.notNull(runnable, "Runnable must not be null"); this.runnable = runnable; } + /** + * Return the underlying task. + */ public Runnable getRunnable() { - return runnable; + return this.runnable; } + + + @Override + public String toString() { + return this.runnable.toString(); + } + } diff --git a/spring-context/src/main/java/org/springframework/scheduling/config/TriggerTask.java b/spring-context/src/main/java/org/springframework/scheduling/config/TriggerTask.java index 0766d6580e..5bea7d0e76 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/config/TriggerTask.java +++ b/spring-context/src/main/java/org/springframework/scheduling/config/TriggerTask.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.springframework.scheduling.config; import org.springframework.scheduling.Trigger; +import org.springframework.util.Assert; /** * {@link Task} implementation defining a {@code Runnable} to be executed @@ -24,8 +25,7 @@ import org.springframework.scheduling.Trigger; * * @author Chris Beams * @since 3.2 - * @see Trigger#nextExecutionTime(org.springframework.scheduling.TriggerContext) - * @see ScheduledTaskRegistrar#setTriggerTasksList(java.util.List) + * @see ScheduledTaskRegistrar#addTriggerTask(TriggerTask) * @see org.springframework.scheduling.TaskScheduler#schedule(Runnable, Trigger) */ public class TriggerTask extends Task { @@ -40,10 +40,14 @@ public class TriggerTask extends Task { */ public TriggerTask(Runnable runnable, Trigger trigger) { super(runnable); + Assert.notNull(trigger, "Trigger must not be null"); this.trigger = trigger; } + /** + * Return the associated trigger. + */ public Trigger getTrigger() { return this.trigger; } diff --git a/spring-context/src/main/java/org/springframework/scheduling/support/ScheduledMethodRunnable.java b/spring-context/src/main/java/org/springframework/scheduling/support/ScheduledMethodRunnable.java index 63beb9b180..7c1fd599f2 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/support/ScheduledMethodRunnable.java +++ b/spring-context/src/main/java/org/springframework/scheduling/support/ScheduledMethodRunnable.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -72,4 +72,9 @@ public class ScheduledMethodRunnable implements Runnable { } } + @Override + public String toString() { + return this.method.getDeclaringClass().getName() + "." + this.method.getName(); + } + } diff --git a/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableSchedulingTests.java b/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableSchedulingTests.java index 4cbdbb7305..183ff810b0 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableSchedulingTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/annotation/EnableSchedulingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,7 @@ import org.springframework.scheduling.Trigger; import org.springframework.scheduling.TriggerContext; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.scheduling.config.IntervalTask; +import org.springframework.scheduling.config.ScheduledTaskHolder; import org.springframework.scheduling.config.ScheduledTaskRegistrar; import org.springframework.scheduling.config.TaskManagementConfigUtils; import org.springframework.tests.Assume; @@ -64,6 +65,7 @@ public class EnableSchedulingTests { Assume.group(TestGroup.PERFORMANCE); ctx = new AnnotationConfigApplicationContext(FixedRateTaskConfig.class); + assertEquals(2, ctx.getBean(ScheduledTaskHolder.class).getScheduledTasks().size()); Thread.sleep(100); assertThat(ctx.getBean(AtomicInteger.class).get(), greaterThanOrEqualTo(10)); @@ -74,6 +76,7 @@ public class EnableSchedulingTests { Assume.group(TestGroup.PERFORMANCE); ctx = new AnnotationConfigApplicationContext(FixedRateTaskConfigSubclass.class); + assertEquals(2, ctx.getBean(ScheduledTaskHolder.class).getScheduledTasks().size()); Thread.sleep(100); assertThat(ctx.getBean(AtomicInteger.class).get(), greaterThanOrEqualTo(10)); @@ -84,6 +87,7 @@ public class EnableSchedulingTests { Assume.group(TestGroup.PERFORMANCE); ctx = new AnnotationConfigApplicationContext(ExplicitSchedulerConfig.class); + assertEquals(1, ctx.getBean(ScheduledTaskHolder.class).getScheduledTasks().size()); Thread.sleep(100); assertThat(ctx.getBean(AtomicInteger.class).get(), greaterThanOrEqualTo(10)); @@ -103,6 +107,7 @@ public class EnableSchedulingTests { Assume.group(TestGroup.PERFORMANCE); ctx = new AnnotationConfigApplicationContext(ExplicitScheduledTaskRegistrarConfig.class); + assertEquals(1, ctx.getBean(ScheduledTaskHolder.class).getScheduledTasks().size()); Thread.sleep(100); assertThat(ctx.getBean(AtomicInteger.class).get(), greaterThanOrEqualTo(10)); @@ -179,7 +184,12 @@ public class EnableSchedulingTests { @Configuration @EnableScheduling - static class FixedRateTaskConfig { + static class FixedRateTaskConfig implements SchedulingConfigurer { + + @Override + public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { + taskRegistrar.addFixedRateTask(() -> {}, 100); + } @Bean public AtomicInteger counter() {