Browse Source

@Scheduled supports java.time.Duration format for its delay attributes

Issue: SPR-15455
pull/1653/head
Juergen Hoeller 7 years ago
parent
commit
13c735442c
  1. 5
      spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java
  2. 24
      spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java
  3. 30
      spring-context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java

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

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2018 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.
@ -86,6 +86,7 @@ public @interface Scheduled { @@ -86,6 +86,7 @@ public @interface Scheduled {
* Execute the annotated method with a fixed period in milliseconds 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
* or a {@link java.time.Duration#parse java.time.Duration} compliant value
* @since 3.2.2
*/
String fixedDelayString() default "";
@ -101,6 +102,7 @@ public @interface Scheduled { @@ -101,6 +102,7 @@ public @interface Scheduled {
* Execute the annotated method with a fixed period in milliseconds between
* invocations.
* @return the period 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 fixedRateString() default "";
@ -117,6 +119,7 @@ public @interface Scheduled { @@ -117,6 +119,7 @@ public @interface Scheduled {
* Number of milliseconds to delay before the first execution of a
* {@link #fixedRate()} or {@link #fixedDelay()} task.
* @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 "";

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

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
package org.springframework.scheduling.annotation;
import java.lang.reflect.Method;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@ -362,9 +363,9 @@ public class ScheduledAnnotationBeanPostProcessor @@ -362,9 +363,9 @@ public class ScheduledAnnotationBeanPostProcessor
}
if (StringUtils.hasLength(initialDelayString)) {
try {
initialDelay = Long.parseLong(initialDelayString);
initialDelay = parseDelayAsLong(initialDelayString);
}
catch (NumberFormatException ex) {
catch (RuntimeException ex) {
throw new IllegalArgumentException(
"Invalid initialDelayString value \"" + initialDelayString + "\" - cannot parse into long");
}
@ -414,9 +415,9 @@ public class ScheduledAnnotationBeanPostProcessor @@ -414,9 +415,9 @@ public class ScheduledAnnotationBeanPostProcessor
Assert.isTrue(!processedSchedule, errorMessage);
processedSchedule = true;
try {
fixedDelay = Long.parseLong(fixedDelayString);
fixedDelay = parseDelayAsLong(fixedDelayString);
}
catch (NumberFormatException ex) {
catch (RuntimeException ex) {
throw new IllegalArgumentException(
"Invalid fixedDelayString value \"" + fixedDelayString + "\" - cannot parse into long");
}
@ -440,9 +441,9 @@ public class ScheduledAnnotationBeanPostProcessor @@ -440,9 +441,9 @@ public class ScheduledAnnotationBeanPostProcessor
Assert.isTrue(!processedSchedule, errorMessage);
processedSchedule = true;
try {
fixedRate = Long.parseLong(fixedRateString);
fixedRate = parseDelayAsLong(fixedRateString);
}
catch (NumberFormatException ex) {
catch (RuntimeException ex) {
throw new IllegalArgumentException(
"Invalid fixedRateString value \"" + fixedRateString + "\" - cannot parse into long");
}
@ -469,6 +470,17 @@ public class ScheduledAnnotationBeanPostProcessor @@ -469,6 +470,17 @@ public class ScheduledAnnotationBeanPostProcessor
}
}
private static long parseDelayAsLong(String value) throws RuntimeException {
if (value.length() > 1 && (isP(value.charAt(0)) || isP(value.charAt(1)))) {
return Duration.parse(value).toMillis();
}
return Long.parseLong(value);
}
private static boolean isP(char ch) {
return (ch == 'P' || ch == 'p');
}
/**
* Return all currently scheduled tasks, from {@link Scheduled} methods

30
spring-context/src/test/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessorTests.java

@ -425,12 +425,21 @@ public class ScheduledAnnotationBeanPostProcessorTests { @@ -425,12 +425,21 @@ public class ScheduledAnnotationBeanPostProcessorTests {
}
@Test
public void propertyPlaceholderWithFixedDelay() {
public void propertyPlaceholderWithFixedDelayInMillis() {
propertyPlaceholderWithFixedDelay(false);
}
@Test
public void propertyPlaceholderWithFixedDelayInDuration() {
propertyPlaceholderWithFixedDelay(true);
}
private void propertyPlaceholderWithFixedDelay(boolean durationFormat) {
BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class);
BeanDefinition placeholderDefinition = new RootBeanDefinition(PropertyPlaceholderConfigurer.class);
Properties properties = new Properties();
properties.setProperty("fixedDelay", "5000");
properties.setProperty("initialDelay", "1000");
properties.setProperty("fixedDelay", (durationFormat ? "PT5S" : "5000"));
properties.setProperty("initialDelay", (durationFormat ? "PT1S" : "1000"));
placeholderDefinition.getPropertyValues().addPropertyValue("properties", properties);
BeanDefinition targetDefinition = new RootBeanDefinition(PropertyPlaceholderWithFixedDelayTestBean.class);
context.registerBeanDefinition("postProcessor", processorDefinition);
@ -457,12 +466,21 @@ public class ScheduledAnnotationBeanPostProcessorTests { @@ -457,12 +466,21 @@ public class ScheduledAnnotationBeanPostProcessorTests {
}
@Test
public void propertyPlaceholderWithFixedRate() {
public void propertyPlaceholderWithFixedRateInMillis() {
propertyPlaceholderWithFixedRate(false);
}
@Test
public void propertyPlaceholderWithFixedRateInDuration() {
propertyPlaceholderWithFixedRate(true);
}
private void propertyPlaceholderWithFixedRate(boolean durationFormat) {
BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class);
BeanDefinition placeholderDefinition = new RootBeanDefinition(PropertyPlaceholderConfigurer.class);
Properties properties = new Properties();
properties.setProperty("fixedRate", "3000");
properties.setProperty("initialDelay", "1000");
properties.setProperty("fixedRate", (durationFormat ? "PT3S" : "3000"));
properties.setProperty("initialDelay", (durationFormat ? "PT1S" : "1000"));
placeholderDefinition.getPropertyValues().addPropertyValue("properties", properties);
BeanDefinition targetDefinition = new RootBeanDefinition(PropertyPlaceholderWithFixedRateTestBean.class);
context.registerBeanDefinition("postProcessor", processorDefinition);

Loading…
Cancel
Save