Support TimeUnit in the @Scheduled annotation
This commit introduces a new `timeUnit` attribute in the @Scheduled annotation to allow the user to specify a time unit other than milliseconds. Closes gh-27309
This commit is contained in:
parent
3c2dfebf4e
commit
e99b43b91e
|
@ -22,6 +22,7 @@ import java.lang.annotation.Repeatable;
|
|||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
||||
|
||||
|
@ -46,6 +47,7 @@ import org.springframework.scheduling.config.ScheduledTaskRegistrar;
|
|||
* @author Juergen Hoeller
|
||||
* @author Dave Syer
|
||||
* @author Chris Beams
|
||||
* @author Victor Brown
|
||||
* @since 3.0
|
||||
* @see EnableScheduling
|
||||
* @see ScheduledAnnotationBeanPostProcessor
|
||||
|
@ -101,52 +103,64 @@ public @interface Scheduled {
|
|||
String zone() default "";
|
||||
|
||||
/**
|
||||
* Execute the annotated method with a fixed period in milliseconds between the
|
||||
* Execute the annotated method with a fixed period between the
|
||||
* end of the last invocation and the start of the next.
|
||||
* @return the delay in milliseconds
|
||||
* Using milliseconds by default with timeUnit().
|
||||
* @return the delay
|
||||
*/
|
||||
long fixedDelay() default -1;
|
||||
|
||||
/**
|
||||
* Execute the annotated method with a fixed period in milliseconds between the
|
||||
* Execute the annotated method with a fixed period between the
|
||||
* end of the last invocation and the start of the next.
|
||||
* @return the delay in milliseconds as a String value, e.g. a placeholder
|
||||
* Using milliseconds by default with fixedDelayTimeUnit().
|
||||
* @return the delay as a String value, e.g. a placeholder
|
||||
* or a {@link java.time.Duration#parse java.time.Duration} compliant value
|
||||
* @since 3.2.2
|
||||
*/
|
||||
String fixedDelayString() default "";
|
||||
|
||||
/**
|
||||
* Execute the annotated method with a fixed period in milliseconds between
|
||||
* Execute the annotated method with a fixed period between
|
||||
* invocations.
|
||||
* @return the period in milliseconds
|
||||
* Using milliseconds by default with timeUnit().
|
||||
* @return the period
|
||||
*/
|
||||
long fixedRate() default -1;
|
||||
|
||||
/**
|
||||
* Execute the annotated method with a fixed period in milliseconds between
|
||||
* Execute the annotated method with a fixed period between
|
||||
* invocations.
|
||||
* @return the period in milliseconds as a String value, e.g. a placeholder
|
||||
* Using milliseconds by default with fixedRateTimeUnit().
|
||||
* @return the period as a String value, e.g. a placeholder
|
||||
* or a {@link java.time.Duration#parse java.time.Duration} compliant value
|
||||
* @since 3.2.2
|
||||
*/
|
||||
String fixedRateString() default "";
|
||||
|
||||
/**
|
||||
* Number of milliseconds to delay before the first execution of a
|
||||
* Number to delay before the first execution of a
|
||||
* {@link #fixedRate} or {@link #fixedDelay} task.
|
||||
* @return the initial delay in milliseconds
|
||||
* Using milliseconds by default with timeUnit().
|
||||
* @return the initial
|
||||
* @since 3.2
|
||||
*/
|
||||
long initialDelay() default -1;
|
||||
|
||||
/**
|
||||
* Number of milliseconds to delay before the first execution of a
|
||||
* Number to delay before the first execution of a
|
||||
* {@link #fixedRate} or {@link #fixedDelay} task.
|
||||
* Using milliseconds by default with initialDelayTimeUnit().
|
||||
* @return the initial delay in milliseconds as a String value, e.g. a placeholder
|
||||
* or a {@link java.time.Duration#parse java.time.Duration} compliant value
|
||||
* @since 3.2.2
|
||||
*/
|
||||
String initialDelayString() default "";
|
||||
|
||||
/**
|
||||
* Specify the {@link TimeUnit} to use for initialDelay, fixedRate and fixedDelay values.
|
||||
* @return the {@link TimeUnit}, by default milliseconds will be used.
|
||||
*/
|
||||
TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
|
||||
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import java.util.Set;
|
|||
import java.util.TimeZone;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
@ -94,6 +95,7 @@ import org.springframework.util.StringValueResolver;
|
|||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @author Elizabeth Chatman
|
||||
* @author Victor Brown
|
||||
* @since 3.0
|
||||
* @see Scheduled
|
||||
* @see EnableScheduling
|
||||
|
@ -398,7 +400,7 @@ public class ScheduledAnnotationBeanPostProcessor
|
|||
Set<ScheduledTask> tasks = new LinkedHashSet<>(4);
|
||||
|
||||
// Determine initial delay
|
||||
long initialDelay = scheduled.initialDelay();
|
||||
long initialDelay = TimeUnit.MILLISECONDS.convert(scheduled.initialDelay(), scheduled.timeUnit());
|
||||
String initialDelayString = scheduled.initialDelayString();
|
||||
if (StringUtils.hasText(initialDelayString)) {
|
||||
Assert.isTrue(initialDelay < 0, "Specify 'initialDelay' or 'initialDelayString', not both");
|
||||
|
@ -407,7 +409,7 @@ public class ScheduledAnnotationBeanPostProcessor
|
|||
}
|
||||
if (StringUtils.hasLength(initialDelayString)) {
|
||||
try {
|
||||
initialDelay = parseDelayAsLong(initialDelayString);
|
||||
initialDelay = TimeUnit.MILLISECONDS.convert(parseDelayAsLong(initialDelayString), scheduled.timeUnit());
|
||||
}
|
||||
catch (RuntimeException ex) {
|
||||
throw new IllegalArgumentException(
|
||||
|
@ -446,12 +448,13 @@ public class ScheduledAnnotationBeanPostProcessor
|
|||
}
|
||||
|
||||
// Check fixed delay
|
||||
long fixedDelay = scheduled.fixedDelay();
|
||||
long fixedDelay = TimeUnit.MILLISECONDS.convert(scheduled.fixedDelay(), scheduled.timeUnit());
|
||||
if (fixedDelay >= 0) {
|
||||
Assert.isTrue(!processedSchedule, errorMessage);
|
||||
processedSchedule = true;
|
||||
tasks.add(this.registrar.scheduleFixedDelayTask(new FixedDelayTask(runnable, fixedDelay, initialDelay)));
|
||||
}
|
||||
|
||||
String fixedDelayString = scheduled.fixedDelayString();
|
||||
if (StringUtils.hasText(fixedDelayString)) {
|
||||
if (this.embeddedValueResolver != null) {
|
||||
|
@ -461,7 +464,7 @@ public class ScheduledAnnotationBeanPostProcessor
|
|||
Assert.isTrue(!processedSchedule, errorMessage);
|
||||
processedSchedule = true;
|
||||
try {
|
||||
fixedDelay = parseDelayAsLong(fixedDelayString);
|
||||
fixedDelay = TimeUnit.MILLISECONDS.convert(parseDelayAsLong(fixedDelayString), scheduled.timeUnit());
|
||||
}
|
||||
catch (RuntimeException ex) {
|
||||
throw new IllegalArgumentException(
|
||||
|
@ -472,7 +475,7 @@ public class ScheduledAnnotationBeanPostProcessor
|
|||
}
|
||||
|
||||
// Check fixed rate
|
||||
long fixedRate = scheduled.fixedRate();
|
||||
long fixedRate = TimeUnit.MILLISECONDS.convert(scheduled.fixedRate(), scheduled.timeUnit());
|
||||
if (fixedRate >= 0) {
|
||||
Assert.isTrue(!processedSchedule, errorMessage);
|
||||
processedSchedule = true;
|
||||
|
@ -487,7 +490,7 @@ public class ScheduledAnnotationBeanPostProcessor
|
|||
Assert.isTrue(!processedSchedule, errorMessage);
|
||||
processedSchedule = true;
|
||||
try {
|
||||
fixedRate = parseDelayAsLong(fixedRateString);
|
||||
fixedRate = TimeUnit.MILLISECONDS.convert(parseDelayAsLong(fixedRateString), scheduled.timeUnit());
|
||||
}
|
||||
catch (RuntimeException ex) {
|
||||
throw new IllegalArgumentException(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -29,6 +29,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -67,6 +68,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
|||
* @author Chris Beams
|
||||
* @author Sam Brannen
|
||||
* @author Stevo Slavić
|
||||
* @author Victor Brown
|
||||
*/
|
||||
public class ScheduledAnnotationBeanPostProcessorTests {
|
||||
|
||||
|
@ -107,6 +109,62 @@ public class ScheduledAnnotationBeanPostProcessorTests {
|
|||
assertThat(task.getInterval()).isEqualTo(5000L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fixedDelayWithSecondsTimeUnitTask() {
|
||||
BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class);
|
||||
BeanDefinition targetDefinition = new RootBeanDefinition(FixedDelayWithSecondsTimeUnitTestBean.class);
|
||||
context.registerBeanDefinition("postProcessor", processorDefinition);
|
||||
context.registerBeanDefinition("target", targetDefinition);
|
||||
context.refresh();
|
||||
|
||||
ScheduledTaskHolder postProcessor = context.getBean("postProcessor", ScheduledTaskHolder.class);
|
||||
assertThat(postProcessor.getScheduledTasks().size()).isEqualTo(1);
|
||||
|
||||
Object target = context.getBean("target");
|
||||
ScheduledTaskRegistrar registrar = (ScheduledTaskRegistrar)
|
||||
new DirectFieldAccessor(postProcessor).getPropertyValue("registrar");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<IntervalTask> fixedDelayTasks = (List<IntervalTask>)
|
||||
new DirectFieldAccessor(registrar).getPropertyValue("fixedDelayTasks");
|
||||
assertThat(fixedDelayTasks.size()).isEqualTo(1);
|
||||
IntervalTask task = fixedDelayTasks.get(0);
|
||||
ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task.getRunnable();
|
||||
Object targetObject = runnable.getTarget();
|
||||
Method targetMethod = runnable.getMethod();
|
||||
assertThat(targetObject).isEqualTo(target);
|
||||
assertThat(targetMethod.getName()).isEqualTo("fixedDelay");
|
||||
assertThat(task.getInitialDelay()).isEqualTo(0L);
|
||||
assertThat(task.getInterval()).isEqualTo(5000L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fixedDelayWithMinutesTimeUnitTask() {
|
||||
BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class);
|
||||
BeanDefinition targetDefinition = new RootBeanDefinition(FixedDelayWithMinutesTimeUnitTestBean.class);
|
||||
context.registerBeanDefinition("postProcessor", processorDefinition);
|
||||
context.registerBeanDefinition("target", targetDefinition);
|
||||
context.refresh();
|
||||
|
||||
ScheduledTaskHolder postProcessor = context.getBean("postProcessor", ScheduledTaskHolder.class);
|
||||
assertThat(postProcessor.getScheduledTasks().size()).isEqualTo(1);
|
||||
|
||||
Object target = context.getBean("target");
|
||||
ScheduledTaskRegistrar registrar = (ScheduledTaskRegistrar)
|
||||
new DirectFieldAccessor(postProcessor).getPropertyValue("registrar");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<IntervalTask> fixedDelayTasks = (List<IntervalTask>)
|
||||
new DirectFieldAccessor(registrar).getPropertyValue("fixedDelayTasks");
|
||||
assertThat(fixedDelayTasks.size()).isEqualTo(1);
|
||||
IntervalTask task = fixedDelayTasks.get(0);
|
||||
ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task.getRunnable();
|
||||
Object targetObject = runnable.getTarget();
|
||||
Method targetMethod = runnable.getMethod();
|
||||
assertThat(targetObject).isEqualTo(target);
|
||||
assertThat(targetMethod.getName()).isEqualTo("fixedDelay");
|
||||
assertThat(task.getInitialDelay()).isEqualTo(0L);
|
||||
assertThat(task.getInterval()).isEqualTo(180000L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fixedRateTask() {
|
||||
BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class);
|
||||
|
@ -135,6 +193,62 @@ public class ScheduledAnnotationBeanPostProcessorTests {
|
|||
assertThat(task.getInterval()).isEqualTo(3000L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fixedRateWithSecondsTimeUnitTask() {
|
||||
BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class);
|
||||
BeanDefinition targetDefinition = new RootBeanDefinition(FixedRateWithSecondsTimeUnitTestBean.class);
|
||||
context.registerBeanDefinition("postProcessor", processorDefinition);
|
||||
context.registerBeanDefinition("target", targetDefinition);
|
||||
context.refresh();
|
||||
|
||||
ScheduledTaskHolder postProcessor = context.getBean("postProcessor", ScheduledTaskHolder.class);
|
||||
assertThat(postProcessor.getScheduledTasks().size()).isEqualTo(1);
|
||||
|
||||
Object target = context.getBean("target");
|
||||
ScheduledTaskRegistrar registrar = (ScheduledTaskRegistrar)
|
||||
new DirectFieldAccessor(postProcessor).getPropertyValue("registrar");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<IntervalTask> fixedRateTasks = (List<IntervalTask>)
|
||||
new DirectFieldAccessor(registrar).getPropertyValue("fixedRateTasks");
|
||||
assertThat(fixedRateTasks.size()).isEqualTo(1);
|
||||
IntervalTask task = fixedRateTasks.get(0);
|
||||
ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task.getRunnable();
|
||||
Object targetObject = runnable.getTarget();
|
||||
Method targetMethod = runnable.getMethod();
|
||||
assertThat(targetObject).isEqualTo(target);
|
||||
assertThat(targetMethod.getName()).isEqualTo("fixedRate");
|
||||
assertThat(task.getInitialDelay()).isEqualTo(0L);
|
||||
assertThat(task.getInterval()).isEqualTo(5000L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fixedRateWithMinutesTimeUnitTask() {
|
||||
BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class);
|
||||
BeanDefinition targetDefinition = new RootBeanDefinition(FixedRateWithMinutesTimeUnitTestBean.class);
|
||||
context.registerBeanDefinition("postProcessor", processorDefinition);
|
||||
context.registerBeanDefinition("target", targetDefinition);
|
||||
context.refresh();
|
||||
|
||||
ScheduledTaskHolder postProcessor = context.getBean("postProcessor", ScheduledTaskHolder.class);
|
||||
assertThat(postProcessor.getScheduledTasks().size()).isEqualTo(1);
|
||||
|
||||
Object target = context.getBean("target");
|
||||
ScheduledTaskRegistrar registrar = (ScheduledTaskRegistrar)
|
||||
new DirectFieldAccessor(postProcessor).getPropertyValue("registrar");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<IntervalTask> fixedRateTasks = (List<IntervalTask>)
|
||||
new DirectFieldAccessor(registrar).getPropertyValue("fixedRateTasks");
|
||||
assertThat(fixedRateTasks.size()).isEqualTo(1);
|
||||
IntervalTask task = fixedRateTasks.get(0);
|
||||
ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task.getRunnable();
|
||||
Object targetObject = runnable.getTarget();
|
||||
Method targetMethod = runnable.getMethod();
|
||||
assertThat(targetObject).isEqualTo(target);
|
||||
assertThat(targetMethod.getName()).isEqualTo("fixedRate");
|
||||
assertThat(task.getInitialDelay()).isEqualTo(0L);
|
||||
assertThat(task.getInterval()).isEqualTo(180000L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fixedRateTaskWithInitialDelay() {
|
||||
BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class);
|
||||
|
@ -163,6 +277,62 @@ public class ScheduledAnnotationBeanPostProcessorTests {
|
|||
assertThat(task.getInterval()).isEqualTo(3000L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fixedRateTaskWithSecondsTimeUnitWithInitialDelay() {
|
||||
BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class);
|
||||
BeanDefinition targetDefinition = new RootBeanDefinition(FixedRateWithSecondsTimeUnitInitialDelayTestBean.class);
|
||||
context.registerBeanDefinition("postProcessor", processorDefinition);
|
||||
context.registerBeanDefinition("target", targetDefinition);
|
||||
context.refresh();
|
||||
|
||||
ScheduledTaskHolder postProcessor = context.getBean("postProcessor", ScheduledTaskHolder.class);
|
||||
assertThat(postProcessor.getScheduledTasks().size()).isEqualTo(1);
|
||||
|
||||
Object target = context.getBean("target");
|
||||
ScheduledTaskRegistrar registrar = (ScheduledTaskRegistrar)
|
||||
new DirectFieldAccessor(postProcessor).getPropertyValue("registrar");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<IntervalTask> fixedRateTasks = (List<IntervalTask>)
|
||||
new DirectFieldAccessor(registrar).getPropertyValue("fixedRateTasks");
|
||||
assertThat(fixedRateTasks.size()).isEqualTo(1);
|
||||
IntervalTask task = fixedRateTasks.get(0);
|
||||
ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task.getRunnable();
|
||||
Object targetObject = runnable.getTarget();
|
||||
Method targetMethod = runnable.getMethod();
|
||||
assertThat(targetObject).isEqualTo(target);
|
||||
assertThat(targetMethod.getName()).isEqualTo("fixedRate");
|
||||
assertThat(task.getInitialDelay()).isEqualTo(5000L);
|
||||
assertThat(task.getInterval()).isEqualTo(3000L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fixedRateTaskWithMinutesTimeUnitWithInitialDelay() {
|
||||
BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class);
|
||||
BeanDefinition targetDefinition = new RootBeanDefinition(FixedRateWithMinutesTimeUnitInitialDelayTestBean.class);
|
||||
context.registerBeanDefinition("postProcessor", processorDefinition);
|
||||
context.registerBeanDefinition("target", targetDefinition);
|
||||
context.refresh();
|
||||
|
||||
ScheduledTaskHolder postProcessor = context.getBean("postProcessor", ScheduledTaskHolder.class);
|
||||
assertThat(postProcessor.getScheduledTasks().size()).isEqualTo(1);
|
||||
|
||||
Object target = context.getBean("target");
|
||||
ScheduledTaskRegistrar registrar = (ScheduledTaskRegistrar)
|
||||
new DirectFieldAccessor(postProcessor).getPropertyValue("registrar");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<IntervalTask> fixedRateTasks = (List<IntervalTask>)
|
||||
new DirectFieldAccessor(registrar).getPropertyValue("fixedRateTasks");
|
||||
assertThat(fixedRateTasks.size()).isEqualTo(1);
|
||||
IntervalTask task = fixedRateTasks.get(0);
|
||||
ScheduledMethodRunnable runnable = (ScheduledMethodRunnable) task.getRunnable();
|
||||
Object targetObject = runnable.getTarget();
|
||||
Method targetMethod = runnable.getMethod();
|
||||
assertThat(targetObject).isEqualTo(target);
|
||||
assertThat(targetMethod.getName()).isEqualTo("fixedRate");
|
||||
assertThat(task.getInitialDelay()).isEqualTo(60000L);
|
||||
assertThat(task.getInterval()).isEqualTo(180000L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void severalFixedRatesWithRepeatedScheduledAnnotation() {
|
||||
BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class);
|
||||
|
@ -702,6 +872,22 @@ public class ScheduledAnnotationBeanPostProcessorTests {
|
|||
}
|
||||
}
|
||||
|
||||
static class FixedDelayWithSecondsTimeUnitTestBean {
|
||||
|
||||
@Scheduled(fixedDelay = 5, timeUnit = TimeUnit.SECONDS)
|
||||
public void fixedDelay() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class FixedDelayWithMinutesTimeUnitTestBean {
|
||||
|
||||
@Scheduled(fixedDelay = 3, timeUnit = TimeUnit.MINUTES)
|
||||
public void fixedDelay() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static class FixedRateTestBean {
|
||||
|
||||
|
@ -709,6 +895,20 @@ public class ScheduledAnnotationBeanPostProcessorTests {
|
|||
public void fixedRate() {
|
||||
}
|
||||
}
|
||||
static class FixedRateWithSecondsTimeUnitTestBean {
|
||||
|
||||
@Scheduled(fixedRate = 5, timeUnit = TimeUnit.SECONDS)
|
||||
public void fixedRate() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class FixedRateWithMinutesTimeUnitTestBean {
|
||||
|
||||
@Scheduled(fixedRate = 3, timeUnit = TimeUnit.MINUTES)
|
||||
public void fixedRate() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class FixedRateWithInitialDelayTestBean {
|
||||
|
@ -718,6 +918,20 @@ public class ScheduledAnnotationBeanPostProcessorTests {
|
|||
}
|
||||
}
|
||||
|
||||
static class FixedRateWithSecondsTimeUnitInitialDelayTestBean {
|
||||
|
||||
@Scheduled(fixedRate = 3, initialDelay = 5, timeUnit = TimeUnit.SECONDS)
|
||||
public void fixedRate() {
|
||||
}
|
||||
}
|
||||
|
||||
static class FixedRateWithMinutesTimeUnitInitialDelayTestBean {
|
||||
|
||||
@Scheduled(fixedRate = 3, initialDelay = 1, timeUnit = TimeUnit.MINUTES)
|
||||
public void fixedRate() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class SeveralFixedRatesWithSchedulesContainerAnnotationTestBean {
|
||||
|
||||
|
|
Loading…
Reference in New Issue