Skip to content

Commit

Permalink
@scheduled supports java.time.Duration format for its delay attributes
Browse files Browse the repository at this point in the history
Issue: SPR-15455
  • Loading branch information
jhoeller committed Jan 25, 2018
1 parent ef3f93e commit 13c7354
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -86,6 +86,7 @@
* 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 "";
Expand All @@ -101,6 +102,7 @@
* 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 "";
Expand All @@ -117,6 +119,7 @@
* 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 "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -362,9 +363,9 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
}
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");
}
Expand Down Expand Up @@ -414,9 +415,9 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
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");
}
Expand All @@ -440,9 +441,9 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
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");
}
Expand All @@ -469,6 +470,17 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
}
}

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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -425,12 +425,21 @@ public void propertyPlaceholderWithCron() {
}

@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);
Expand All @@ -457,12 +466,21 @@ public void propertyPlaceholderWithFixedDelay() {
}

@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);
Expand Down

0 comments on commit 13c7354

Please sign in to comment.