Skip to content

Commit 91297d9

Browse files
committed
SPR-6307 Quartz SchedulerFactoryBean now "auto-starts" upon receiving a ContextRefreshedEvent rather than within afterPropertiesSet().
1 parent 40720ab commit 91297d9

File tree

2 files changed

+64
-8
lines changed

2 files changed

+64
-8
lines changed

Diff for: org.springframework.context.support/src/main/java/org/springframework/scheduling/quartz/SchedulerFactoryBean.java

+23-6
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,17 @@
3232
import org.quartz.spi.JobFactory;
3333

3434
import org.springframework.beans.BeanUtils;
35+
import org.springframework.beans.factory.BeanInitializationException;
3536
import org.springframework.beans.factory.BeanNameAware;
3637
import org.springframework.beans.factory.DisposableBean;
3738
import org.springframework.beans.factory.FactoryBean;
3839
import org.springframework.beans.factory.InitializingBean;
3940
import org.springframework.context.ApplicationContext;
4041
import org.springframework.context.ApplicationContextAware;
42+
import org.springframework.context.ApplicationEvent;
43+
import org.springframework.context.ApplicationListener;
4144
import org.springframework.context.Lifecycle;
45+
import org.springframework.context.event.ContextRefreshedEvent;
4246
import org.springframework.core.io.Resource;
4347
import org.springframework.core.io.ResourceLoader;
4448
import org.springframework.core.io.support.PropertiesLoaderUtils;
@@ -87,7 +91,8 @@
8791
* @see org.springframework.transaction.interceptor.TransactionProxyFactoryBean
8892
*/
8993
public class SchedulerFactoryBean extends SchedulerAccessor
90-
implements FactoryBean<Scheduler>, BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean, Lifecycle {
94+
implements FactoryBean<Scheduler>, BeanNameAware, ApplicationContextAware,
95+
ApplicationListener<ApplicationEvent>, InitializingBean, DisposableBean, Lifecycle {
9196

9297
public static final String PROP_THREAD_COUNT = "org.quartz.threadPool.threadCount";
9398

@@ -481,11 +486,6 @@ public void afterPropertiesSet() throws Exception {
481486

482487
registerListeners();
483488
registerJobsAndTriggers();
484-
485-
// Start Scheduler immediately, if demanded.
486-
if (this.autoStartup) {
487-
startScheduler(this.scheduler, this.startupDelay);
488-
}
489489
}
490490

491491

@@ -678,6 +678,23 @@ public boolean isSingleton() {
678678
}
679679

680680

681+
//---------------------------------------------------------------------
682+
// Implementation of ApplicationListener interface
683+
//---------------------------------------------------------------------
684+
685+
public void onApplicationEvent(ApplicationEvent event) {
686+
// auto-start Scheduler if demanded
687+
if (event instanceof ContextRefreshedEvent && this.autoStartup) {
688+
try {
689+
startScheduler(this.scheduler, this.startupDelay);
690+
}
691+
catch (SchedulerException e) {
692+
throw new BeanInitializationException("failed to auto-start scheduler", e);
693+
}
694+
}
695+
}
696+
697+
681698
//---------------------------------------------------------------------
682699
// Implementation of Lifecycle interface
683700
//---------------------------------------------------------------------

Diff for: org.springframework.context.support/src/test/java/org/springframework/scheduling/quartz/QuartzSupportTests.java

+41-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2008 the original author or authors.
2+
* Copyright 2002-2009 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
1717
package org.springframework.scheduling.quartz;
1818

1919
import static org.junit.Assert.assertEquals;
20+
import static org.junit.Assert.assertFalse;
2021
import static org.junit.Assert.assertNotSame;
2122
import static org.junit.Assert.assertSame;
2223
import static org.junit.Assert.assertTrue;
@@ -29,7 +30,6 @@
2930

3031
import javax.sql.DataSource;
3132

32-
import junit.framework.TestCase;
3333
import org.easymock.MockControl;
3434
import org.junit.Test;
3535
import org.quartz.CronTrigger;
@@ -51,6 +51,9 @@
5151
import org.quartz.spi.JobFactory;
5252

5353
import org.springframework.beans.TestBean;
54+
import org.springframework.beans.factory.config.BeanDefinition;
55+
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
56+
import org.springframework.beans.factory.support.RootBeanDefinition;
5457
import org.springframework.beans.factory.support.StaticListableBeanFactory;
5558
import org.springframework.context.support.ClassPathXmlApplicationContext;
5659
import org.springframework.context.support.StaticApplicationContext;
@@ -64,6 +67,7 @@
6467
* @author Alef Arendsen
6568
* @author Rob Harrop
6669
* @author Dave Syer
70+
* @author Mark Fisher
6771
* @since 20.02.2004
6872
*/
6973
public class QuartzSupportTests {
@@ -164,6 +168,7 @@ protected Scheduler createScheduler(SchedulerFactory schedulerFactory, String sc
164168
schedulerFactoryBean.setTriggers(new Trigger[] {trigger0, trigger1});
165169
try {
166170
schedulerFactoryBean.afterPropertiesSet();
171+
schedulerFactoryBean.start();
167172
}
168173
finally {
169174
schedulerFactoryBean.destroy();
@@ -257,6 +262,7 @@ protected Scheduler createScheduler(SchedulerFactory schedulerFactory, String sc
257262
}
258263
try {
259264
schedulerFactoryBean.afterPropertiesSet();
265+
schedulerFactoryBean.start();
260266
}
261267
finally {
262268
schedulerFactoryBean.destroy();
@@ -354,6 +360,7 @@ protected Scheduler createScheduler(SchedulerFactory schedulerFactory, String sc
354360
}
355361
try {
356362
schedulerFactoryBean.afterPropertiesSet();
363+
schedulerFactoryBean.start();
357364
}
358365
finally {
359366
schedulerFactoryBean.destroy();
@@ -406,6 +413,7 @@ protected Scheduler createScheduler(SchedulerFactory schedulerFactory, String sc
406413
schedulerFactoryBean.setTriggerListeners(new TriggerListener[] {triggerListener});
407414
try {
408415
schedulerFactoryBean.afterPropertiesSet();
416+
schedulerFactoryBean.start();
409417
}
410418
finally {
411419
schedulerFactoryBean.destroy();
@@ -571,6 +579,7 @@ protected Scheduler createScheduler(SchedulerFactory schedulerFactory, String sc
571579
schedulerFactoryBean.setTriggers(new Trigger[] {trigger0, trigger1});
572580
try {
573581
schedulerFactoryBean.afterPropertiesSet();
582+
schedulerFactoryBean.start();
574583
}
575584
finally {
576585
schedulerFactoryBean.destroy();
@@ -608,6 +617,7 @@ protected Scheduler createScheduler(SchedulerFactory schedulerFactory, String sc
608617
schedulerFactoryBean.setApplicationContextSchedulerContextKey("appCtx");
609618
try {
610619
schedulerFactoryBean.afterPropertiesSet();
620+
schedulerFactoryBean.start();
611621
Scheduler returnedScheduler = (Scheduler) schedulerFactoryBean.getObject();
612622
assertEquals(tb, returnedScheduler.getContext().get("testBean"));
613623
assertEquals(ac, returnedScheduler.getContext().get("appCtx"));
@@ -703,6 +713,7 @@ public void testSchedulerWithTaskExecutor() throws Exception {
703713
bean.setTriggers(new Trigger[] {trigger});
704714
bean.setJobDetails(new JobDetail[] {jobDetail});
705715
bean.afterPropertiesSet();
716+
bean.start();
706717

707718
Thread.sleep(500);
708719
assertTrue(DummyJob.count > 0);
@@ -731,6 +742,7 @@ public void testSchedulerWithRunnable() throws Exception {
731742
bean.setTriggers(new Trigger[] {trigger});
732743
bean.setJobDetails(new JobDetail[] {jobDetail});
733744
bean.afterPropertiesSet();
745+
bean.start();
734746

735747
Thread.sleep(500);
736748
assertTrue(DummyRunnable.count > 0);
@@ -760,6 +772,7 @@ public void testSchedulerWithQuartzJobBean() throws Exception {
760772
bean.setTriggers(new Trigger[] {trigger});
761773
bean.setJobDetails(new JobDetail[] {jobDetail});
762774
bean.afterPropertiesSet();
775+
bean.start();
763776

764777
Thread.sleep(500);
765778
assertEquals(10, DummyJobBean.param);
@@ -792,6 +805,7 @@ public void testSchedulerWithSpringBeanJobFactory() throws Exception {
792805
bean.setTriggers(new Trigger[] {trigger});
793806
bean.setJobDetails(new JobDetail[] {jobDetail});
794807
bean.afterPropertiesSet();
808+
bean.start();
795809

796810
Thread.sleep(500);
797811
assertEquals(10, DummyJob.param);
@@ -857,6 +871,7 @@ public void testSchedulerWithSpringBeanJobFactoryAndRunnable() throws Exception
857871
bean.setTriggers(new Trigger[] {trigger});
858872
bean.setJobDetails(new JobDetail[] {jobDetail});
859873
bean.afterPropertiesSet();
874+
bean.start();
860875

861876
Thread.sleep(500);
862877
assertEquals(10, DummyRunnable.param);
@@ -888,6 +903,7 @@ public void testSchedulerWithSpringBeanJobFactoryAndQuartzJobBean() throws Excep
888903
bean.setTriggers(new Trigger[] {trigger});
889904
bean.setJobDetails(new JobDetail[] {jobDetail});
890905
bean.afterPropertiesSet();
906+
bean.start();
891907

892908
Thread.sleep(500);
893909
assertEquals(10, DummyJobBean.param);
@@ -906,6 +922,7 @@ public void testSchedulerWithSpringBeanJobFactoryAndJobSchedulingData() throws E
906922
bean.setJobSchedulingDataLocation("org/springframework/scheduling/quartz/job-scheduling-data.xml");
907923
bean.setResourceLoader(new FileSystemResourceLoader());
908924
bean.afterPropertiesSet();
925+
bean.start();
909926

910927
Thread.sleep(500);
911928
assertEquals(10, DummyJob.param);
@@ -971,6 +988,28 @@ public void testSchedulerAccessorBean() throws InterruptedException {
971988
}
972989
}
973990

991+
@Test
992+
public void testSchedulerAutoStartsOnContextRefreshedEventByDefault() throws Exception {
993+
StaticApplicationContext context = new StaticApplicationContext();
994+
context.registerBeanDefinition("scheduler", new RootBeanDefinition(SchedulerFactoryBean.class));
995+
Scheduler bean = context.getBean("scheduler", Scheduler.class);
996+
assertFalse(bean.isStarted());
997+
context.refresh();
998+
assertTrue(bean.isStarted());
999+
}
1000+
1001+
@Test
1002+
public void testSchedulerAutoStartupFalse() throws Exception {
1003+
StaticApplicationContext context = new StaticApplicationContext();
1004+
BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(
1005+
SchedulerFactoryBean.class).addPropertyValue("autoStartup", false).getBeanDefinition();
1006+
context.registerBeanDefinition("scheduler", beanDefinition);
1007+
Scheduler bean = context.getBean("scheduler", Scheduler.class);
1008+
assertFalse(bean.isStarted());
1009+
context.refresh();
1010+
assertFalse(bean.isStarted());
1011+
}
1012+
9741013
@Test
9751014
public void testSchedulerRepositoryExposure() throws InterruptedException {
9761015
ClassPathXmlApplicationContext ctx =

0 commit comments

Comments
 (0)