Expose more Quartz properties

Closes gh-13782
pull/13779/merge
Stephane Nicoll 6 years ago
parent 0eeba7bf38
commit 3c67edafcd

@ -90,6 +90,12 @@ public class QuartzAutoConfiguration {
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
schedulerFactoryBean.setJobFactory(new AutowireCapableBeanJobFactory( schedulerFactoryBean.setJobFactory(new AutowireCapableBeanJobFactory(
this.applicationContext.getAutowireCapableBeanFactory())); this.applicationContext.getAutowireCapableBeanFactory()));
schedulerFactoryBean.setBeanName(this.properties.getSchedulerName());
schedulerFactoryBean.setAutoStartup(this.properties.isAutoStartup());
schedulerFactoryBean
.setStartupDelay((int) this.properties.getStartupDelay().getSeconds());
schedulerFactoryBean.setWaitForJobsToCompleteOnShutdown(
this.properties.isWaitForJobsToCompleteOnShutdown());
schedulerFactoryBean schedulerFactoryBean
.setOverwriteExistingJobs(this.properties.isOverwriteExistingJobs()); .setOverwriteExistingJobs(this.properties.isOverwriteExistingJobs());
if (!this.properties.getProperties().isEmpty()) { if (!this.properties.getProperties().isEmpty()) {

@ -16,6 +16,7 @@
package org.springframework.boot.autoconfigure.quartz; package org.springframework.boot.autoconfigure.quartz;
import java.time.Duration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -37,6 +38,28 @@ public class QuartzProperties {
*/ */
private JobStoreType jobStoreType = JobStoreType.MEMORY; private JobStoreType jobStoreType = JobStoreType.MEMORY;
/**
* Name of the scheduler.
*/
private String schedulerName = "quartzScheduler";
/**
* Whether to automatically start the scheduler after initialization.
*/
private boolean autoStartup = true;
/**
* Delay after which the scheduler is started once initialization completes. Setting
* this property makes sense if no jobs should be run before the entire application
* has started up.
*/
private Duration startupDelay = Duration.ofSeconds(0);
/**
* Whether to wait for running jobs to complete on shutdown.
*/
private boolean waitForJobsToCompleteOnShutdown = false;
/** /**
* Whether configured jobs should overwrite existing job definitions. * Whether configured jobs should overwrite existing job definitions.
*/ */
@ -57,6 +80,39 @@ public class QuartzProperties {
this.jobStoreType = jobStoreType; this.jobStoreType = jobStoreType;
} }
public String getSchedulerName() {
return this.schedulerName;
}
public void setSchedulerName(String schedulerName) {
this.schedulerName = schedulerName;
}
public boolean isAutoStartup() {
return this.autoStartup;
}
public void setAutoStartup(boolean autoStartup) {
this.autoStartup = autoStartup;
}
public Duration getStartupDelay() {
return this.startupDelay;
}
public void setStartupDelay(Duration startupDelay) {
this.startupDelay = startupDelay;
}
public boolean isWaitForJobsToCompleteOnShutdown() {
return this.waitForJobsToCompleteOnShutdown;
}
public void setWaitForJobsToCompleteOnShutdown(
boolean waitForJobsToCompleteOnShutdown) {
this.waitForJobsToCompleteOnShutdown = waitForJobsToCompleteOnShutdown;
}
public boolean isOverwriteExistingJobs() { public boolean isOverwriteExistingJobs() {
return this.overwriteExistingJobs; return this.overwriteExistingJobs;
} }

@ -37,6 +37,7 @@ import org.quartz.impl.calendar.MonthlyCalendar;
import org.quartz.impl.calendar.WeeklyCalendar; import org.quartz.impl.calendar.WeeklyCalendar;
import org.quartz.simpl.RAMJobStore; import org.quartz.simpl.RAMJobStore;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@ -54,6 +55,7 @@ import org.springframework.core.env.Environment;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.quartz.LocalDataSourceJobStore; import org.springframework.scheduling.quartz.LocalDataSourceJobStore;
import org.springframework.scheduling.quartz.QuartzJobBean; import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -224,6 +226,51 @@ public class QuartzAutoConfigurationTests {
}); });
} }
@Test
public void validateDefaultProperties() {
this.contextRunner.withUserConfiguration(ManualSchedulerConfiguration.class)
.run((context) -> {
assertThat(context).hasSingleBean(SchedulerFactoryBean.class);
SchedulerFactoryBean schedulerFactory = context
.getBean(SchedulerFactoryBean.class);
DirectFieldAccessor dfa = new DirectFieldAccessor(schedulerFactory);
QuartzProperties properties = new QuartzProperties();
assertThat(properties.isAutoStartup())
.isEqualTo(schedulerFactory.isAutoStartup());
assertThat((int) properties.getStartupDelay().getSeconds())
.isEqualTo(dfa.getPropertyValue("startupDelay"));
assertThat(properties.isWaitForJobsToCompleteOnShutdown()).isEqualTo(
dfa.getPropertyValue("waitForJobsToCompleteOnShutdown"));
assertThat(properties.isOverwriteExistingJobs())
.isEqualTo(dfa.getPropertyValue("overwriteExistingJobs"));
});
}
@Test
public void withCustomConfiguration() {
this.contextRunner.withPropertyValues(
"spring.quartz.scheduler-name=testScheduler",
"spring.quartz.auto-startup=false", "spring.quartz.startup-delay=1m",
"spring.quartz.wait-for-jobs-to-complete-on-shutdown=true",
"spring.quartz.wait-for-jobs-to-complete-on-shutdown=true",
"spring.quartz.overwrite-existing-jobs=true").run((context) -> {
assertThat(context).hasSingleBean(SchedulerFactoryBean.class);
SchedulerFactoryBean schedulerFactory = context
.getBean(SchedulerFactoryBean.class);
DirectFieldAccessor dfa = new DirectFieldAccessor(schedulerFactory);
assertThat(dfa.getPropertyValue("schedulerName"))
.isEqualTo("testScheduler");
assertThat(schedulerFactory.isAutoStartup()).isFalse();
assertThat(dfa.getPropertyValue("startupDelay")).isEqualTo(60);
assertThat(dfa.getPropertyValue("waitForJobsToCompleteOnShutdown"))
.isEqualTo(true);
assertThat(dfa.getPropertyValue("overwriteExistingJobs"))
.isEqualTo(true);
});
}
@Import(ComponentThatUsesScheduler.class) @Import(ComponentThatUsesScheduler.class)
@Configuration @Configuration
protected static class BaseQuartzConfiguration { protected static class BaseQuartzConfiguration {
@ -318,6 +365,16 @@ public class QuartzAutoConfigurationTests {
} }
@Configuration
protected static class ManualSchedulerConfiguration {
@Bean
public SchedulerFactoryBean quartzScheduler() {
return new SchedulerFactoryBean();
}
}
@Configuration @Configuration
protected static class MultipleDataSourceConfiguration protected static class MultipleDataSourceConfiguration
extends BaseQuartzConfiguration { extends BaseQuartzConfiguration {

@ -141,12 +141,16 @@ content into your application. Rather, pick only the properties that you need.
spring.profiles.include= # Unconditionally activate the specified comma-separated list of profiles (or list of profiles if using YAML). spring.profiles.include= # Unconditionally activate the specified comma-separated list of profiles (or list of profiles if using YAML).
# QUARTZ SCHEDULER ({sc-spring-boot-autoconfigure}/quartz/QuartzProperties.{sc-ext}[QuartzProperties]) # QUARTZ SCHEDULER ({sc-spring-boot-autoconfigure}/quartz/QuartzProperties.{sc-ext}[QuartzProperties])
spring.quartz.auto-startup=true # Whether to automatically start the scheduler after initialization.
spring.quartz.jdbc.comment-prefix=-- # Prefix for single-line comments in SQL initialization scripts. spring.quartz.jdbc.comment-prefix=-- # Prefix for single-line comments in SQL initialization scripts.
spring.quartz.jdbc.initialize-schema=embedded # Database schema initialization mode. spring.quartz.jdbc.initialize-schema=embedded # Database schema initialization mode.
spring.quartz.jdbc.schema=classpath:org/quartz/impl/jdbcjobstore/tables_@@platform@@.sql # Path to the SQL file to use to initialize the database schema. spring.quartz.jdbc.schema=classpath:org/quartz/impl/jdbcjobstore/tables_@@platform@@.sql # Path to the SQL file to use to initialize the database schema.
spring.quartz.job-store-type=memory # Quartz job store type. spring.quartz.job-store-type=memory # Quartz job store type.
spring.quartz.properties.*= # Additional Quartz Scheduler properties. spring.quartz.properties.*= # Additional Quartz Scheduler properties.
spring.quartz.scheduler-name=quartzScheduler # Name of the scheduler.
spring.quartz.startup-delay=0s # Delay after which the scheduler is started once initialization completes.
spring.quartz.overwrite-existing-jobs=false # Whether configured jobs should overwrite existing job definitions. spring.quartz.overwrite-existing-jobs=false # Whether configured jobs should overwrite existing job definitions.
spring.quartz.wait-for-jobs-to-complete-on-shutdown=false # Whether to wait for running jobs to complete on shutdown.
# REACTOR ({sc-spring-boot-autoconfigure}/reactor/core/ReactorCoreProperties.{sc-ext}[ReactorCoreProperties]) # REACTOR ({sc-spring-boot-autoconfigure}/reactor/core/ReactorCoreProperties.{sc-ext}[ReactorCoreProperties])
spring.reactor.stacktrace-mode.enabled=false # Whether Reactor should collect stacktrace information at runtime. spring.reactor.stacktrace-mode.enabled=false # Whether Reactor should collect stacktrace information at runtime.

@ -6000,9 +6000,10 @@ By default, jobs created by configuration will not overwrite already registered
have been read from a persistent job store. To enable overwriting existing job definitions have been read from a persistent job store. To enable overwriting existing job definitions
set the `spring.quartz.overwrite-existing-jobs` property. set the `spring.quartz.overwrite-existing-jobs` property.
Quartz Scheduler configuration can be customized by using Quartz configuration properties Quartz Scheduler configuration can be customized using `spring.quartz` properties and
(`spring.quartz.properties.*`) and `SchedulerFactoryBeanCustomizer` beans, which allow `SchedulerFactoryBeanCustomizer` beans, which allow programmatic `SchedulerFactoryBean`
programmatic `SchedulerFactoryBean` customization. customization. Advanced Quartz configuration properties can be customized using
`spring.quartz.properties.*`.
NOTE: In particular, an `Executor` bean is not associated with the scheduler as Quartz NOTE: In particular, an `Executor` bean is not associated with the scheduler as Quartz
offers a way to configure the scheduler via `spring.quartz.properties`. If you need offers a way to configure the scheduler via `spring.quartz.properties`. If you need

Loading…
Cancel
Save