Browse Source

fixed @Scheduled processing to kick in once only even in an ApplicationContext hierarchy (SPR-6656)

git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@2794 50f2f4bb-b051-0410-bef5-90022cba6387
pull/1/head
Juergen Hoeller 16 years ago
parent
commit
ff228e3977
  1. 45
      org.springframework.context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java

45
org.springframework.context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java

@ -24,6 +24,8 @@ import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener; import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
@ -35,19 +37,23 @@ import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils.MethodCallback; import org.springframework.util.ReflectionUtils.MethodCallback;
/** /**
* Bean post-processor that registers methods annotated with * Bean post-processor that registers methods annotated with {@link Scheduled @Scheduled}
* {@link Scheduled @Scheduled} to be invoked by a TaskScheduler according * to be invoked by a {@link org.springframework.scheduling.TaskScheduler} according
* to the fixedRate, fixedDelay, or cron expression provided via the annotation. * to the "fixedRate", "fixedDelay", or "cron" expression provided via the annotation.
* *
* @author Mark Fisher * @author Mark Fisher
* @author Juergen Hoeller
* @since 3.0 * @since 3.0
* @see Scheduled * @see Scheduled
* @see org.springframework.scheduling.TaskScheduler
*/ */
public class ScheduledAnnotationBeanPostProcessor implements BeanPostProcessor, Ordered, public class ScheduledAnnotationBeanPostProcessor implements BeanPostProcessor, Ordered,
ApplicationListener<ContextRefreshedEvent>, DisposableBean { ApplicationContextAware, ApplicationListener<ContextRefreshedEvent>, DisposableBean {
private Object scheduler; private Object scheduler;
private ApplicationContext applicationContext;
private final ScheduledTaskRegistrar registrar = new ScheduledTaskRegistrar(); private final ScheduledTaskRegistrar registrar = new ScheduledTaskRegistrar();
private final Map<Runnable, String> cronTasks = new HashMap<Runnable, String>(); private final Map<Runnable, String> cronTasks = new HashMap<Runnable, String>();
@ -58,20 +64,23 @@ public class ScheduledAnnotationBeanPostProcessor implements BeanPostProcessor,
/** /**
* Set the {@link org.springframework.scheduling.TaskScheduler} that will * Set the {@link org.springframework.scheduling.TaskScheduler} that will invoke
* invoke the scheduled methods or a * the scheduled methods, or a {@link java.util.concurrent.ScheduledExecutorService}
* {@link java.util.concurrent.ScheduledExecutorService} to be wrapped * to be wrapped as a TaskScheduler.
* within an instance of
* {@link org.springframework.scheduling.concurrent.ConcurrentTaskScheduler}.
*/ */
public void setScheduler(Object scheduler) { public void setScheduler(Object scheduler) {
this.scheduler = scheduler; this.scheduler = scheduler;
} }
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
public int getOrder() { public int getOrder() {
return LOWEST_PRECEDENCE; return LOWEST_PRECEDENCE;
} }
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean; return bean;
} }
@ -110,13 +119,13 @@ public class ScheduledAnnotationBeanPostProcessor implements BeanPostProcessor,
if (fixedDelay >= 0) { if (fixedDelay >= 0) {
Assert.isTrue(!processedSchedule, errorMessage); Assert.isTrue(!processedSchedule, errorMessage);
processedSchedule = true; processedSchedule = true;
fixedDelayTasks.put(runnable, new Long(fixedDelay)); fixedDelayTasks.put(runnable, fixedDelay);
} }
long fixedRate = annotation.fixedRate(); long fixedRate = annotation.fixedRate();
if (fixedRate >= 0) { if (fixedRate >= 0) {
Assert.isTrue(!processedSchedule, errorMessage); Assert.isTrue(!processedSchedule, errorMessage);
processedSchedule = true; processedSchedule = true;
fixedRateTasks.put(runnable, new Long(fixedRate)); fixedRateTasks.put(runnable, fixedRate);
} }
Assert.isTrue(processedSchedule, errorMessage); Assert.isTrue(processedSchedule, errorMessage);
} }
@ -126,13 +135,15 @@ public class ScheduledAnnotationBeanPostProcessor implements BeanPostProcessor,
} }
public void onApplicationEvent(ContextRefreshedEvent event) { public void onApplicationEvent(ContextRefreshedEvent event) {
if (scheduler != null) { if (event.getApplicationContext() == this.applicationContext) {
this.registrar.setScheduler(scheduler); if (this.scheduler != null) {
this.registrar.setScheduler(this.scheduler);
}
this.registrar.setCronTasks(this.cronTasks);
this.registrar.setFixedDelayTasks(this.fixedDelayTasks);
this.registrar.setFixedRateTasks(this.fixedRateTasks);
this.registrar.afterPropertiesSet();
} }
this.registrar.setCronTasks(this.cronTasks);
this.registrar.setFixedDelayTasks(this.fixedDelayTasks);
this.registrar.setFixedRateTasks(this.fixedRateTasks);
this.registrar.afterPropertiesSet();
} }
public void destroy() throws Exception { public void destroy() throws Exception {

Loading…
Cancel
Save