Allow for custom ScheduledTaskRegistrar and/or ScheduledMethodRunnable

Issue: SPR-16834
Issue: SPR-16812
This commit is contained in:
Juergen Hoeller 2018-06-13 22:03:01 +02:00
parent 0078f46779
commit 9aed9bf823
1 changed files with 46 additions and 7 deletions

View File

@ -115,6 +115,8 @@ public class ScheduledAnnotationBeanPostProcessor
protected final Log logger = LogFactory.getLog(getClass());
private final ScheduledTaskRegistrar registrar;
@Nullable
private Object scheduler;
@ -130,13 +132,30 @@ public class ScheduledAnnotationBeanPostProcessor
@Nullable
private ApplicationContext applicationContext;
private final ScheduledTaskRegistrar registrar = new ScheduledTaskRegistrar();
private final Set<Class<?>> nonAnnotatedClasses = Collections.newSetFromMap(new ConcurrentHashMap<>(64));
private final Map<Object, Set<ScheduledTask>> scheduledTasks = new IdentityHashMap<>(16);
/**
* Create a default {@code ScheduledAnnotationBeanPostProcessor}.
*/
public ScheduledAnnotationBeanPostProcessor() {
this.registrar = new ScheduledTaskRegistrar();
}
/**
* Create a {@code ScheduledAnnotationBeanPostProcessor} delegating to the
* specified {@link ScheduledTaskRegistrar}.
* @param registrar the ScheduledTaskRegistrar to register @Scheduled tasks on
* @since 5.1
*/
public ScheduledAnnotationBeanPostProcessor(ScheduledTaskRegistrar registrar) {
Assert.notNull(registrar, "ScheduledTaskRegistrar is required");
this.registrar = registrar;
}
@Override
public int getOrder() {
return LOWEST_PRECEDENCE;
@ -340,13 +359,16 @@ public class ScheduledAnnotationBeanPostProcessor
return bean;
}
/**
* Process the given {@code @Scheduled} method declaration on the given bean.
* @param scheduled the @Scheduled annotation
* @param method the method that the annotation has been declared on
* @param bean the target bean instance
* @see #createRunnable(Object, Method)
*/
protected void processScheduled(Scheduled scheduled, Method method, Object bean) {
try {
Assert.isTrue(method.getParameterCount() == 0,
"Only no-arg methods may be annotated with @Scheduled");
Method invocableMethod = AopUtils.selectInvocableMethod(method, bean.getClass());
Runnable runnable = new ScheduledMethodRunnable(bean, invocableMethod);
Runnable runnable = createRunnable(bean, method);
boolean processedSchedule = false;
String errorMessage =
"Exactly one of the 'cron', 'fixedDelay(String)', or 'fixedRate(String)' attributes is required";
@ -470,6 +492,23 @@ public class ScheduledAnnotationBeanPostProcessor
}
}
/**
* Create a {@link Runnable} for the given bean instance,
* calling the specified scheduled method.
* <p>The default implementation creates a {@link ScheduledMethodRunnable}.
* @param target the target bean instance
* @param method the scheduled method to call
* @since 5.1
* @see ScheduledMethodRunnable#ScheduledMethodRunnable(Object, Method)
*/
protected Runnable createRunnable(Object target, Method method) {
Assert.isTrue(method.getParameterCount() == 0,
"Only no-arg methods may be annotated with @Scheduled");
Method invocableMethod = AopUtils.selectInvocableMethod(method, target.getClass());
return new ScheduledMethodRunnable(target, invocableMethod);
}
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();