diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzAutoConfiguration.java index 1753e0476144..763215958aac 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/QuartzAutoConfiguration.java @@ -33,6 +33,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; @@ -87,14 +88,6 @@ public QuartzAutoConfiguration(QuartzProperties properties, this.applicationContext = applicationContext; } - @Bean - @ConditionalOnSingleCandidate(DataSource.class) - @ConditionalOnMissingBean - public QuartzDatabaseInitializer quartzDatabaseInitializer(DataSource dataSource, - ResourceLoader resourceLoader) { - return new QuartzDatabaseInitializer(dataSource, resourceLoader, this.properties); - } - @Bean @ConditionalOnMissingBean public SchedulerFactoryBean quartzScheduler() { @@ -137,24 +130,42 @@ private void customize(SchedulerFactoryBean schedulerFactoryBean) { @Configuration @ConditionalOnSingleCandidate(DataSource.class) + @ConditionalOnProperty(prefix = "spring.quartz", name = "job-store-type", havingValue = "jdbc") protected static class JdbcStoreTypeConfiguration { @Bean - public SchedulerFactoryBeanCustomizer dataSourceCustomizer( - QuartzProperties properties, DataSource dataSource, + public static InitializerSchedulerDependencyPostProcessor initializerSchedulerDependencyPostProcessor() { + return new InitializerSchedulerDependencyPostProcessor(); + } + + @Bean + @ConditionalOnMissingBean + public QuartzDatabaseInitializer quartzDatabaseInitializer(DataSource dataSource, + ResourceLoader resourceLoader, QuartzProperties properties) { + return new QuartzDatabaseInitializer(dataSource, resourceLoader, properties); + } + + @Bean + public SchedulerFactoryBeanCustomizer dataSourceCustomizer(DataSource dataSource, ObjectProvider transactionManager) { return schedulerFactoryBean -> { - if (properties.getJobStoreType() == JobStoreType.JDBC) { - schedulerFactoryBean.setDataSource(dataSource); - PlatformTransactionManager txManager = transactionManager - .getIfUnique(); - if (txManager != null) { - schedulerFactoryBean.setTransactionManager(txManager); - } + schedulerFactoryBean.setDataSource(dataSource); + PlatformTransactionManager txManager = transactionManager.getIfUnique(); + if (txManager != null) { + schedulerFactoryBean.setTransactionManager(txManager); } }; } + private static class InitializerSchedulerDependencyPostProcessor + extends SchedulerDependsOnPostProcessor { + + InitializerSchedulerDependencyPostProcessor() { + super("quartzDatabaseInitializer"); + } + + } + } } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/SchedulerDependsOnPostProcessor.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/SchedulerDependsOnPostProcessor.java new file mode 100644 index 000000000000..fc2b387063e4 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/quartz/SchedulerDependsOnPostProcessor.java @@ -0,0 +1,41 @@ +/* + * Copyright 2012-2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.quartz; + +import org.quartz.Scheduler; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.boot.autoconfigure.AbstractDependsOnBeanFactoryPostProcessor; +import org.springframework.scheduling.quartz.SchedulerFactoryBean; + +/** + * {@link BeanFactoryPostProcessor} that can be used to dynamically declare that all + * {@link Scheduler} beans should "depend on" one or more specific beans. + * + * @author Vedran Pavic + * @since 2.0.0 + * @see BeanDefinition#setDependsOn(String[]) + */ +public class SchedulerDependsOnPostProcessor + extends AbstractDependsOnBeanFactoryPostProcessor { + + public SchedulerDependsOnPostProcessor(String... dependsOn) { + super(Scheduler.class, SchedulerFactoryBean.class, dependsOn); + } + +} diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/quartz/QuartzAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/quartz/QuartzAutoConfigurationTests.java index 06665d1e154e..ef95c44480e3 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/quartz/QuartzAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/quartz/QuartzAutoConfigurationTests.java @@ -174,7 +174,7 @@ public void withQuartzProperties() throws Exception { @Test public void withCustomizer() throws Exception { - load(QuartzCustomConfig.class); + load(QuartzCustomConfiguration.class); assertThat(this.context.getBeansOfType(Scheduler.class)).hasSize(1); Scheduler scheduler = this.context.getBean(Scheduler.class); assertThat(scheduler.getSchedulerName()).isEqualTo("fooScheduler"); @@ -199,8 +199,17 @@ private void load(Class[] configs, String... environment) { this.context = ctx; } + protected static class BaseQuartzConfiguration { + + @Bean + public ComponentThatUsesScheduler component() { + return new ComponentThatUsesScheduler(); + } + + } + @Configuration - protected static class QuartzJobsConfiguration { + protected static class QuartzJobsConfiguration extends BaseQuartzConfiguration { @Bean public JobDetail fooJob() { @@ -217,7 +226,7 @@ public JobDetail barJob() { } @Configuration - protected static class QuartzFullConfiguration { + protected static class QuartzFullConfiguration extends BaseQuartzConfiguration { @Bean public JobDetail fooJob() { @@ -237,7 +246,7 @@ public Trigger fooTrigger() { } @Configuration - protected static class QuartzCalendarsConfiguration { + protected static class QuartzCalendarsConfiguration extends BaseQuartzConfiguration { @Bean public Calendar weekly() { @@ -252,7 +261,7 @@ public Calendar monthly() { } @Configuration - protected static class QuartzExecutorConfiguration { + protected static class QuartzExecutorConfiguration extends BaseQuartzConfiguration { @Bean public Executor executor() { @@ -262,7 +271,7 @@ public Executor executor() { } @Configuration - protected static class QuartzCustomConfig { + protected static class QuartzCustomConfiguration extends BaseQuartzConfiguration { @Bean public SchedulerFactoryBeanCustomizer customizer() { @@ -272,6 +281,13 @@ public SchedulerFactoryBeanCustomizer customizer() { } + public static class ComponentThatUsesScheduler { + + @Autowired + private Scheduler scheduler; + + } + public static class FooJob extends QuartzJobBean { @Autowired diff --git a/spring-boot-samples/spring-boot-sample-quartz/pom.xml b/spring-boot-samples/spring-boot-sample-quartz/pom.xml index a161afa0be62..b37ab99ace3b 100644 --- a/spring-boot-samples/spring-boot-sample-quartz/pom.xml +++ b/spring-boot-samples/spring-boot-sample-quartz/pom.xml @@ -23,6 +23,14 @@ org.springframework.boot spring-boot-starter-quartz + + org.springframework.boot + spring-boot-starter-jdbc + + + com.h2database + h2 + diff --git a/spring-boot-samples/spring-boot-sample-quartz/src/main/java/sample/quartz/SampleQuartzApplication.java b/spring-boot-samples/spring-boot-sample-quartz/src/main/java/sample/quartz/SampleQuartzApplication.java index 0836fa78a44c..8d5f6711bef6 100644 --- a/spring-boot-samples/spring-boot-sample-quartz/src/main/java/sample/quartz/SampleQuartzApplication.java +++ b/spring-boot-samples/spring-boot-sample-quartz/src/main/java/sample/quartz/SampleQuartzApplication.java @@ -18,26 +18,40 @@ import org.quartz.JobBuilder; import org.quartz.JobDetail; +import org.quartz.Scheduler; import org.quartz.SimpleScheduleBuilder; import org.quartz.Trigger; import org.quartz.TriggerBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; @SpringBootApplication -public class SampleQuartzApplication { +public class SampleQuartzApplication implements CommandLineRunner { + + @Autowired + private Scheduler scheduler; public static void main(String[] args) { SpringApplication.run(SampleQuartzApplication.class, args); } + @Override + public void run(String... args) throws Exception { + Trigger trigger = TriggerBuilder.newTrigger().forJob(sampleJobDetail()) + .withIdentity("startTrigger").usingJobData("name", "Boot").startNow() + .build(); + + this.scheduler.scheduleJob(trigger); + } + @Bean public JobDetail sampleJobDetail() { - return JobBuilder.newJob().ofType(SampleJob.class).withIdentity("sampleJob") - .usingJobData("name", "World") - .storeDurably().build(); + return JobBuilder.newJob(SampleJob.class).withIdentity("sampleJob") + .usingJobData("name", "World").storeDurably().build(); } @Bean diff --git a/spring-boot-samples/spring-boot-sample-quartz/src/main/resources/application.properties b/spring-boot-samples/spring-boot-sample-quartz/src/main/resources/application.properties new file mode 100644 index 000000000000..59e9a98a3d83 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-quartz/src/main/resources/application.properties @@ -0,0 +1,2 @@ +spring.quartz.job-store-type=jdbc +spring.quartz.jdbc.initialize-schema=true