65
65
import org .springframework .scheduling .config .CronTask ;
66
66
import org .springframework .scheduling .config .FixedDelayTask ;
67
67
import org .springframework .scheduling .config .FixedRateTask ;
68
+ import org .springframework .scheduling .config .OneTimeTask ;
68
69
import org .springframework .scheduling .config .ScheduledTask ;
69
70
import org .springframework .scheduling .config .ScheduledTaskHolder ;
70
71
import org .springframework .scheduling .config .ScheduledTaskRegistrar ;
@@ -393,8 +394,7 @@ private void processScheduledAsync(Scheduled scheduled, Method method, Object be
393
394
private void processScheduledTask (Scheduled scheduled , Runnable runnable , Method method , Object bean ) {
394
395
try {
395
396
boolean processedSchedule = false ;
396
- String errorMessage =
397
- "Exactly one of the 'cron', 'fixedDelay(String)', or 'fixedRate(String)' attributes is required" ;
397
+ String errorMessage = "Exactly one of the 'cron', 'fixedDelay' or 'fixedRate' attributes is required" ;
398
398
399
399
Set <ScheduledTask > tasks = new LinkedHashSet <>(4 );
400
400
@@ -442,18 +442,15 @@ private void processScheduledTask(Scheduled scheduled, Runnable runnable, Method
442
442
}
443
443
444
444
// At this point we don't need to differentiate between initial delay set or not anymore
445
- if (initialDelay .isNegative ()) {
446
- initialDelay = Duration .ZERO ;
447
- }
445
+ Duration delayToUse = (initialDelay .isNegative () ? Duration .ZERO : initialDelay );
448
446
449
447
// Check fixed delay
450
448
Duration fixedDelay = toDuration (scheduled .fixedDelay (), scheduled .timeUnit ());
451
449
if (!fixedDelay .isNegative ()) {
452
450
Assert .isTrue (!processedSchedule , errorMessage );
453
451
processedSchedule = true ;
454
- tasks .add (this .registrar .scheduleFixedDelayTask (new FixedDelayTask (runnable , fixedDelay , initialDelay )));
452
+ tasks .add (this .registrar .scheduleFixedDelayTask (new FixedDelayTask (runnable , fixedDelay , delayToUse )));
455
453
}
456
-
457
454
String fixedDelayString = scheduled .fixedDelayString ();
458
455
if (StringUtils .hasText (fixedDelayString )) {
459
456
if (this .embeddedValueResolver != null ) {
@@ -469,7 +466,7 @@ private void processScheduledTask(Scheduled scheduled, Runnable runnable, Method
469
466
throw new IllegalArgumentException (
470
467
"Invalid fixedDelayString value \" " + fixedDelayString + "\" - cannot parse into long" );
471
468
}
472
- tasks .add (this .registrar .scheduleFixedDelayTask (new FixedDelayTask (runnable , fixedDelay , initialDelay )));
469
+ tasks .add (this .registrar .scheduleFixedDelayTask (new FixedDelayTask (runnable , fixedDelay , delayToUse )));
473
470
}
474
471
}
475
472
@@ -478,7 +475,7 @@ private void processScheduledTask(Scheduled scheduled, Runnable runnable, Method
478
475
if (!fixedRate .isNegative ()) {
479
476
Assert .isTrue (!processedSchedule , errorMessage );
480
477
processedSchedule = true ;
481
- tasks .add (this .registrar .scheduleFixedRateTask (new FixedRateTask (runnable , fixedRate , initialDelay )));
478
+ tasks .add (this .registrar .scheduleFixedRateTask (new FixedRateTask (runnable , fixedRate , delayToUse )));
482
479
}
483
480
String fixedRateString = scheduled .fixedRateString ();
484
481
if (StringUtils .hasText (fixedRateString )) {
@@ -495,12 +492,16 @@ private void processScheduledTask(Scheduled scheduled, Runnable runnable, Method
495
492
throw new IllegalArgumentException (
496
493
"Invalid fixedRateString value \" " + fixedRateString + "\" - cannot parse into long" );
497
494
}
498
- tasks .add (this .registrar .scheduleFixedRateTask (new FixedRateTask (runnable , fixedRate , initialDelay )));
495
+ tasks .add (this .registrar .scheduleFixedRateTask (new FixedRateTask (runnable , fixedRate , delayToUse )));
499
496
}
500
497
}
501
498
502
- // Check whether we had any attribute set
503
- Assert .isTrue (processedSchedule , errorMessage );
499
+ if (!processedSchedule ) {
500
+ if (initialDelay .isNegative ()) {
501
+ throw new IllegalArgumentException ("One-time task only supported with specified initial delay" );
502
+ }
503
+ tasks .add (this .registrar .scheduleOneTimeTask (new OneTimeTask (runnable , delayToUse )));
504
+ }
504
505
505
506
// Finally register the scheduled tasks
506
507
synchronized (this .scheduledTasks ) {
@@ -548,7 +549,13 @@ protected Runnable createRunnable(Object target, Method method) {
548
549
}
549
550
550
551
private static Duration toDuration (long value , TimeUnit timeUnit ) {
551
- return Duration .of (value , timeUnit .toChronoUnit ());
552
+ try {
553
+ return Duration .of (value , timeUnit .toChronoUnit ());
554
+ }
555
+ catch (Exception ex ) {
556
+ throw new IllegalArgumentException (
557
+ "Unsupported unit " + timeUnit + " for value \" " + value + "\" : " + ex .getMessage (), ex );
558
+ }
552
559
}
553
560
554
561
private static Duration toDuration (String value , TimeUnit timeUnit ) {
0 commit comments