Skip to content

Commit 9b739a2

Browse files
committed
Update scheduling package to use java.time
This commit deprecates all methods in org.springframework.scheduling that use - Date, in favor of variants that take an Instant. - long & TimeUnit, in favor of variants that take a Duration. Closes: gh-28714
1 parent 8ccf05a commit 9b739a2

File tree

38 files changed

+787
-408
lines changed

38 files changed

+787
-408
lines changed

spring-context/src/main/java/org/springframework/scheduling/TaskScheduler.java

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -89,11 +89,8 @@ default Clock getClock() {
8989
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
9090
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
9191
* @since 5.0
92-
* @see #schedule(Runnable, Date)
9392
*/
94-
default ScheduledFuture<?> schedule(Runnable task, Instant startTime) {
95-
return schedule(task, Date.from(startTime));
96-
}
93+
ScheduledFuture<?> schedule(Runnable task, Instant startTime);
9794

9895
/**
9996
* Schedule the given {@link Runnable}, invoking it at the specified execution time.
@@ -105,8 +102,12 @@ default ScheduledFuture<?> schedule(Runnable task, Instant startTime) {
105102
* @return a {@link ScheduledFuture} representing pending completion of the task
106103
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
107104
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
105+
* @deprecated as of 6.0, in favor of {@link #schedule(Runnable, Instant)}
108106
*/
109-
ScheduledFuture<?> schedule(Runnable task, Date startTime);
107+
@Deprecated
108+
default ScheduledFuture<?> schedule(Runnable task, Date startTime) {
109+
return schedule(task, startTime.toInstant());
110+
}
110111

111112
/**
112113
* Schedule the given {@link Runnable}, invoking it at the specified execution time
@@ -121,11 +122,8 @@ default ScheduledFuture<?> schedule(Runnable task, Instant startTime) {
121122
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
122123
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
123124
* @since 5.0
124-
* @see #scheduleAtFixedRate(Runnable, Date, long)
125125
*/
126-
default ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Instant startTime, Duration period) {
127-
return scheduleAtFixedRate(task, Date.from(startTime), period.toMillis());
128-
}
126+
ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Instant startTime, Duration period);
129127

130128
/**
131129
* Schedule the given {@link Runnable}, invoking it at the specified execution time
@@ -139,8 +137,12 @@ default ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Instant startTime,
139137
* @return a {@link ScheduledFuture} representing pending completion of the task
140138
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
141139
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
140+
* @deprecated as of 6.0, in favor of {@link #scheduleAtFixedRate(Runnable, Instant, Duration)}
142141
*/
143-
ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Date startTime, long period);
142+
@Deprecated
143+
default ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Date startTime, long period) {
144+
return scheduleAtFixedRate(task, startTime.toInstant(), Duration.ofMillis(period));
145+
}
144146

145147
/**
146148
* Schedule the given {@link Runnable}, starting as soon as possible and
@@ -153,11 +155,8 @@ default ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Instant startTime,
153155
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
154156
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
155157
* @since 5.0
156-
* @see #scheduleAtFixedRate(Runnable, long)
157158
*/
158-
default ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Duration period) {
159-
return scheduleAtFixedRate(task, period.toMillis());
160-
}
159+
ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Duration period);
161160

162161
/**
163162
* Schedule the given {@link Runnable}, starting as soon as possible and
@@ -169,8 +168,12 @@ default ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Duration period) {
169168
* @return a {@link ScheduledFuture} representing pending completion of the task
170169
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
171170
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
171+
* @deprecated as of 6.0, in favor of {@link #scheduleAtFixedRate(Runnable, Duration)}
172172
*/
173-
ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long period);
173+
@Deprecated
174+
default ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long period) {
175+
return scheduleAtFixedRate(task, Duration.ofMillis(period));
176+
}
174177

175178
/**
176179
* Schedule the given {@link Runnable}, invoking it at the specified execution time
@@ -186,11 +189,8 @@ default ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Duration period) {
186189
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
187190
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
188191
* @since 5.0
189-
* @see #scheduleWithFixedDelay(Runnable, Date, long)
190192
*/
191-
default ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Instant startTime, Duration delay) {
192-
return scheduleWithFixedDelay(task, Date.from(startTime), delay.toMillis());
193-
}
193+
ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Instant startTime, Duration delay);
194194

195195
/**
196196
* Schedule the given {@link Runnable}, invoking it at the specified execution time
@@ -206,8 +206,12 @@ default ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Instant startTi
206206
* @return a {@link ScheduledFuture} representing pending completion of the task
207207
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
208208
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
209+
* @deprecated as of 6.0, in favor of {@link #scheduleWithFixedDelay(Runnable, Instant, Duration)}
209210
*/
210-
ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Date startTime, long delay);
211+
@Deprecated
212+
default ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Date startTime, long delay) {
213+
return scheduleWithFixedDelay(task, startTime.toInstant(), Duration.ofMillis(delay));
214+
}
211215

212216
/**
213217
* Schedule the given {@link Runnable}, starting as soon as possible and invoking it with
@@ -220,11 +224,8 @@ default ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Instant startTi
220224
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
221225
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
222226
* @since 5.0
223-
* @see #scheduleWithFixedDelay(Runnable, long)
224227
*/
225-
default ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Duration delay) {
226-
return scheduleWithFixedDelay(task, delay.toMillis());
227-
}
228+
ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Duration delay);
228229

229230
/**
230231
* Schedule the given {@link Runnable}, starting as soon as possible and invoking it with
@@ -237,7 +238,11 @@ default ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Duration delay)
237238
* @return a {@link ScheduledFuture} representing pending completion of the task
238239
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
239240
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
241+
* @deprecated as of 6.0, in favor of {@link #scheduleWithFixedDelay(Runnable, Duration)}
240242
*/
241-
ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, long delay);
243+
@Deprecated
244+
default ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, long delay) {
245+
return scheduleWithFixedDelay(task, Duration.ofMillis(delay));
246+
}
242247

243248
}

spring-context/src/main/java/org/springframework/scheduling/Trigger.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.scheduling;
1818

19+
import java.time.Instant;
1920
import java.util.Date;
2021

2122
import org.springframework.lang.Nullable;
@@ -37,8 +38,24 @@ public interface Trigger {
3738
* and last completion time
3839
* @return the next execution time as defined by the trigger,
3940
* or {@code null} if the trigger won't fire anymore
41+
* @deprecated as of 6.0, in favor of {@link #nextExecution(TriggerContext)}
4042
*/
43+
@Deprecated
4144
@Nullable
42-
Date nextExecutionTime(TriggerContext triggerContext);
45+
default Date nextExecutionTime(TriggerContext triggerContext) {
46+
Instant instant = nextExecution(triggerContext);
47+
return instant != null ? Date.from(instant) : null;
48+
}
49+
50+
/**
51+
* Determine the next execution time according to the given trigger context.
52+
* @param triggerContext context object encapsulating last execution times
53+
* and last completion time
54+
* @return the next execution time as defined by the trigger,
55+
* or {@code null} if the trigger won't fire anymore
56+
* @since 6.0
57+
*/
58+
@Nullable
59+
Instant nextExecution(TriggerContext triggerContext);
4360

4461
}

spring-context/src/main/java/org/springframework/scheduling/TriggerContext.java

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -17,6 +17,7 @@
1717
package org.springframework.scheduling;
1818

1919
import java.time.Clock;
20+
import java.time.Instant;
2021
import java.util.Date;
2122

2223
import org.springframework.lang.Nullable;
@@ -43,22 +44,59 @@ default Clock getClock() {
4344
/**
4445
* Return the last <i>scheduled</i> execution time of the task,
4546
* or {@code null} if not scheduled before.
47+
* @deprecated as of 6.0, in favor on {@link #lastScheduledExecution()}
4648
*/
4749
@Nullable
48-
Date lastScheduledExecutionTime();
50+
@Deprecated
51+
default Date lastScheduledExecutionTime() {
52+
Instant instant = lastScheduledExecution();
53+
return instant != null ? Date.from(instant) : null;
54+
}
55+
56+
/**
57+
* Return the last <i>scheduled</i> execution time of the task,
58+
* or {@code null} if not scheduled before.
59+
* @since 6.0
60+
*/
61+
@Nullable
62+
Instant lastScheduledExecution();
4963

5064
/**
5165
* Return the last <i>actual</i> execution time of the task,
5266
* or {@code null} if not scheduled before.
67+
* @deprecated as of 6.0, in favor on {@link #lastActualExecution()}
5368
*/
69+
@Deprecated
5470
@Nullable
55-
Date lastActualExecutionTime();
71+
default Date lastActualExecutionTime() {
72+
Instant instant = lastActualExecution();
73+
return instant != null ? Date.from(instant) : null;
74+
}
75+
76+
/**
77+
* Return the last <i>actual</i> execution time of the task,
78+
* or {@code null} if not scheduled before.
79+
*/
80+
@Nullable
81+
Instant lastActualExecution();
82+
83+
/**
84+
* Return the last completion time of the task,
85+
* or {@code null} if not scheduled before.
86+
* @deprecated as of 6.0, in favor on {@link #lastCompletion()}
87+
*/
88+
@Deprecated
89+
@Nullable
90+
default Date lastCompletionTime() {
91+
Instant instant = lastCompletion();
92+
return instant != null ? Date.from(instant) : null;
93+
}
5694

5795
/**
5896
* Return the last completion time of the task,
5997
* or {@code null} if not scheduled before.
6098
*/
6199
@Nullable
62-
Date lastCompletionTime();
100+
Instant lastCompletion();
63101

64102
}

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

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -405,16 +405,16 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
405405
Set<ScheduledTask> tasks = new LinkedHashSet<>(4);
406406

407407
// Determine initial delay
408-
long initialDelay = convertToMillis(scheduled.initialDelay(), scheduled.timeUnit());
408+
Duration initialDelay = toDuration(scheduled.initialDelay(), scheduled.timeUnit());
409409
String initialDelayString = scheduled.initialDelayString();
410410
if (StringUtils.hasText(initialDelayString)) {
411-
Assert.isTrue(initialDelay < 0, "Specify 'initialDelay' or 'initialDelayString', not both");
411+
Assert.isTrue(initialDelay.isNegative(), "Specify 'initialDelay' or 'initialDelayString', not both");
412412
if (this.embeddedValueResolver != null) {
413413
initialDelayString = this.embeddedValueResolver.resolveStringValue(initialDelayString);
414414
}
415415
if (StringUtils.hasLength(initialDelayString)) {
416416
try {
417-
initialDelay = convertToMillis(initialDelayString, scheduled.timeUnit());
417+
initialDelay = toDuration(initialDelayString, scheduled.timeUnit());
418418
}
419419
catch (RuntimeException ex) {
420420
throw new IllegalArgumentException(
@@ -432,7 +432,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
432432
zone = this.embeddedValueResolver.resolveStringValue(zone);
433433
}
434434
if (StringUtils.hasLength(cron)) {
435-
Assert.isTrue(initialDelay == -1, "'initialDelay' not supported for cron triggers");
435+
Assert.isTrue(initialDelay.isNegative(), "'initialDelay' not supported for cron triggers");
436436
processedSchedule = true;
437437
if (!Scheduled.CRON_DISABLED.equals(cron)) {
438438
TimeZone timeZone;
@@ -448,13 +448,13 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
448448
}
449449

450450
// At this point we don't need to differentiate between initial delay set or not anymore
451-
if (initialDelay < 0) {
452-
initialDelay = 0;
451+
if (initialDelay.isNegative()) {
452+
initialDelay = Duration.ZERO;
453453
}
454454

455455
// Check fixed delay
456-
long fixedDelay = convertToMillis(scheduled.fixedDelay(), scheduled.timeUnit());
457-
if (fixedDelay >= 0) {
456+
Duration fixedDelay = toDuration(scheduled.fixedDelay(), scheduled.timeUnit());
457+
if (!fixedDelay.isNegative()) {
458458
Assert.isTrue(!processedSchedule, errorMessage);
459459
processedSchedule = true;
460460
tasks.add(this.registrar.scheduleFixedDelayTask(new FixedDelayTask(runnable, fixedDelay, initialDelay)));
@@ -469,7 +469,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
469469
Assert.isTrue(!processedSchedule, errorMessage);
470470
processedSchedule = true;
471471
try {
472-
fixedDelay = convertToMillis(fixedDelayString, scheduled.timeUnit());
472+
fixedDelay = toDuration(fixedDelayString, scheduled.timeUnit());
473473
}
474474
catch (RuntimeException ex) {
475475
throw new IllegalArgumentException(
@@ -480,8 +480,8 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
480480
}
481481

482482
// Check fixed rate
483-
long fixedRate = convertToMillis(scheduled.fixedRate(), scheduled.timeUnit());
484-
if (fixedRate >= 0) {
483+
Duration fixedRate = toDuration(scheduled.fixedRate(), scheduled.timeUnit());
484+
if (!fixedRate.isNegative()) {
485485
Assert.isTrue(!processedSchedule, errorMessage);
486486
processedSchedule = true;
487487
tasks.add(this.registrar.scheduleFixedRateTask(new FixedRateTask(runnable, fixedRate, initialDelay)));
@@ -495,7 +495,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
495495
Assert.isTrue(!processedSchedule, errorMessage);
496496
processedSchedule = true;
497497
try {
498-
fixedRate = convertToMillis(fixedRateString, scheduled.timeUnit());
498+
fixedRate = toDuration(fixedRateString, scheduled.timeUnit());
499499
}
500500
catch (RuntimeException ex) {
501501
throw new IllegalArgumentException(
@@ -535,15 +535,15 @@ protected Runnable createRunnable(Object target, Method method) {
535535
return new ScheduledMethodRunnable(target, invocableMethod);
536536
}
537537

538-
private static long convertToMillis(long value, TimeUnit timeUnit) {
539-
return TimeUnit.MILLISECONDS.convert(value, timeUnit);
538+
private static Duration toDuration(long value, TimeUnit timeUnit) {
539+
return Duration.of(value, timeUnit.toChronoUnit());
540540
}
541541

542-
private static long convertToMillis(String value, TimeUnit timeUnit) {
542+
private static Duration toDuration(String value, TimeUnit timeUnit) {
543543
if (isDurationString(value)) {
544-
return Duration.parse(value).toMillis();
544+
return Duration.parse(value);
545545
}
546-
return convertToMillis(Long.parseLong(value), timeUnit);
546+
return toDuration(Long.parseLong(value), timeUnit);
547547
}
548548

549549
private static boolean isDurationString(String value) {

0 commit comments

Comments
 (0)