Skip to content

Commit 9aed9bf

Browse files
committed
Allow for custom ScheduledTaskRegistrar and/or ScheduledMethodRunnable
Issue: SPR-16834 Issue: SPR-16812
1 parent 0078f46 commit 9aed9bf

File tree

1 file changed

+46
-7
lines changed

1 file changed

+46
-7
lines changed

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

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ public class ScheduledAnnotationBeanPostProcessor
115115

116116
protected final Log logger = LogFactory.getLog(getClass());
117117

118+
private final ScheduledTaskRegistrar registrar;
119+
118120
@Nullable
119121
private Object scheduler;
120122

@@ -130,13 +132,30 @@ public class ScheduledAnnotationBeanPostProcessor
130132
@Nullable
131133
private ApplicationContext applicationContext;
132134

133-
private final ScheduledTaskRegistrar registrar = new ScheduledTaskRegistrar();
134-
135135
private final Set<Class<?>> nonAnnotatedClasses = Collections.newSetFromMap(new ConcurrentHashMap<>(64));
136136

137137
private final Map<Object, Set<ScheduledTask>> scheduledTasks = new IdentityHashMap<>(16);
138138

139139

140+
/**
141+
* Create a default {@code ScheduledAnnotationBeanPostProcessor}.
142+
*/
143+
public ScheduledAnnotationBeanPostProcessor() {
144+
this.registrar = new ScheduledTaskRegistrar();
145+
}
146+
147+
/**
148+
* Create a {@code ScheduledAnnotationBeanPostProcessor} delegating to the
149+
* specified {@link ScheduledTaskRegistrar}.
150+
* @param registrar the ScheduledTaskRegistrar to register @Scheduled tasks on
151+
* @since 5.1
152+
*/
153+
public ScheduledAnnotationBeanPostProcessor(ScheduledTaskRegistrar registrar) {
154+
Assert.notNull(registrar, "ScheduledTaskRegistrar is required");
155+
this.registrar = registrar;
156+
}
157+
158+
140159
@Override
141160
public int getOrder() {
142161
return LOWEST_PRECEDENCE;
@@ -340,13 +359,16 @@ public Object postProcessAfterInitialization(final Object bean, String beanName)
340359
return bean;
341360
}
342361

362+
/**
363+
* Process the given {@code @Scheduled} method declaration on the given bean.
364+
* @param scheduled the @Scheduled annotation
365+
* @param method the method that the annotation has been declared on
366+
* @param bean the target bean instance
367+
* @see #createRunnable(Object, Method)
368+
*/
343369
protected void processScheduled(Scheduled scheduled, Method method, Object bean) {
344370
try {
345-
Assert.isTrue(method.getParameterCount() == 0,
346-
"Only no-arg methods may be annotated with @Scheduled");
347-
348-
Method invocableMethod = AopUtils.selectInvocableMethod(method, bean.getClass());
349-
Runnable runnable = new ScheduledMethodRunnable(bean, invocableMethod);
371+
Runnable runnable = createRunnable(bean, method);
350372
boolean processedSchedule = false;
351373
String errorMessage =
352374
"Exactly one of the 'cron', 'fixedDelay(String)', or 'fixedRate(String)' attributes is required";
@@ -470,6 +492,23 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
470492
}
471493
}
472494

495+
/**
496+
* Create a {@link Runnable} for the given bean instance,
497+
* calling the specified scheduled method.
498+
* <p>The default implementation creates a {@link ScheduledMethodRunnable}.
499+
* @param target the target bean instance
500+
* @param method the scheduled method to call
501+
* @since 5.1
502+
* @see ScheduledMethodRunnable#ScheduledMethodRunnable(Object, Method)
503+
*/
504+
protected Runnable createRunnable(Object target, Method method) {
505+
Assert.isTrue(method.getParameterCount() == 0,
506+
"Only no-arg methods may be annotated with @Scheduled");
507+
508+
Method invocableMethod = AopUtils.selectInvocableMethod(method, target.getClass());
509+
return new ScheduledMethodRunnable(target, invocableMethod);
510+
}
511+
473512
private static long parseDelayAsLong(String value) throws RuntimeException {
474513
if (value.length() > 1 && (isP(value.charAt(0)) || isP(value.charAt(1)))) {
475514
return Duration.parse(value).toMillis();

0 commit comments

Comments
 (0)