|
For the latest stable version, please use Spring Boot 3.5.7! |
Quartz Scheduler
Spring Boot offers several conveniences for working with the Quartz scheduler, including the spring-boot-starter-quartz starter.
If Quartz is available, a Scheduler is auto-configured (through the SchedulerFactoryBean abstraction).
Beans of the following types are automatically picked up and associated with the Scheduler:
-
JobDetail: defines a particular Job.JobDetailinstances can be built with theJobBuilderAPI. -
Trigger: defines when a particular job is triggered.
By default, an in-memory JobStore is used.
However, it is possible to configure a JDBC-based store if a DataSource bean is available in your application and if the spring.quartz.job-store-type property is configured accordingly, as shown in the following example:
-
Properties
-
YAML
spring.quartz.job-store-type=jdbc
spring:
quartz:
job-store-type: "jdbc"
When the JDBC store is used, the schema can be initialized on startup, as shown in the following example:
-
Properties
-
YAML
spring.quartz.jdbc.initialize-schema=always
spring:
quartz:
jdbc:
initialize-schema: "always"
By default, the database is detected and initialized by using the standard scripts provided with the Quartz library.
These scripts drop existing tables, deleting all triggers on every restart.
To use a custom script, set the spring.quartz.jdbc.schema property.
Some of the standard scripts – such as those for SQL Server, Azure SQL, and Sybase – cannot be used without modification.
In these cases, make a copy of the script and edit it as directed in the script’s comments then set spring.quartz.jdbc.schema to use your customized script.
|
To have Quartz use a DataSource other than the application’s main DataSource, declare a DataSource bean, annotating its @Bean method with @QuartzDataSource.
Doing so ensures that the Quartz-specific DataSource is used by both the SchedulerFactoryBean and for schema initialization.
Similarly, to have Quartz use a TransactionManager other than the application’s main TransactionManager declare a TransactionManager bean, annotating its @Bean method with @QuartzTransactionManager.
By default, jobs created by configuration will not overwrite already registered jobs that have been read from a persistent job store.
To enable overwriting existing job definitions set the spring.quartz.overwrite-existing-jobs property.
Quartz Scheduler configuration can be customized using spring.quartz properties and SchedulerFactoryBeanCustomizer beans, which allow programmatic SchedulerFactoryBean customization.
Advanced Quartz configuration properties can be customized using spring.quartz.properties.*.
In particular, an Executor bean is not associated with the scheduler as Quartz offers a way to configure the scheduler through spring.quartz.properties.
If you need to customize the task executor, consider implementing SchedulerFactoryBeanCustomizer.
|
Jobs can define setters to inject data map properties. Regular beans can also be injected in a similar manner, as shown in the following example:
-
Java
-
Kotlin
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class MySampleJob extends QuartzJobBean {
// fields ...
private MyService myService;
private String name;
// Inject "MyService" bean
public void setMyService(MyService myService) {
this.myService = myService;
}
// Inject the "name" job data property
public void setName(String name) {
this.name = name;
}
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
this.myService.someMethod(context.getFireTime(), this.name);
}
}
import org.quartz.JobExecutionContext
import org.springframework.scheduling.quartz.QuartzJobBean
class MySampleJob : QuartzJobBean() {
// fields ...
private var myService: MyService? = null
private var name: String? = null
// Inject "MyService" bean
fun setMyService(myService: MyService?) {
this.myService = myService
}
// Inject the "name" job data property
fun setName(name: String?) {
this.name = name
}
override fun executeInternal(context: JobExecutionContext) {
myService!!.someMethod(context.fireTime, name)
}
}