Skip to content

Ensure QuartzDatabaseInitializer is initialized before Scheduler #9411

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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<PlatformTransactionManager> 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");
}

}

}

}
Original file line number Diff line number Diff line change
@@ -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);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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() {
Expand All @@ -217,7 +226,7 @@ public JobDetail barJob() {
}

@Configuration
protected static class QuartzFullConfiguration {
protected static class QuartzFullConfiguration extends BaseQuartzConfiguration {

@Bean
public JobDetail fooJob() {
Expand All @@ -237,7 +246,7 @@ public Trigger fooTrigger() {
}

@Configuration
protected static class QuartzCalendarsConfiguration {
protected static class QuartzCalendarsConfiguration extends BaseQuartzConfiguration {

@Bean
public Calendar weekly() {
Expand All @@ -252,7 +261,7 @@ public Calendar monthly() {
}

@Configuration
protected static class QuartzExecutorConfiguration {
protected static class QuartzExecutorConfiguration extends BaseQuartzConfiguration {

@Bean
public Executor executor() {
Expand All @@ -262,7 +271,7 @@ public Executor executor() {
}

@Configuration
protected static class QuartzCustomConfig {
protected static class QuartzCustomConfiguration extends BaseQuartzConfiguration {

@Bean
public SchedulerFactoryBeanCustomizer customizer() {
Expand All @@ -272,6 +281,13 @@ public SchedulerFactoryBeanCustomizer customizer() {

}

public static class ComponentThatUsesScheduler {

@Autowired
private Scheduler scheduler;

}

public static class FooJob extends QuartzJobBean {

@Autowired
Expand Down
8 changes: 8 additions & 0 deletions spring-boot-samples/spring-boot-sample-quartz/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
spring.quartz.job-store-type=jdbc
spring.quartz.jdbc.initialize-schema=true