https://docs.spring.io/spring-boot/docs/3.2.0/reference/htmlsingle/#io.quartz
Spring Boot 为与 Quartz 调度器一起工作提供了多种便利,包括“spring-boot-starter-quartz
”Starter。如果 Quartz 可用,将自动配置 Scheduler
(通过 SchedulerFactoryBean
抽象)。
以下类型的 Beans 将被自动发现并与 Scheduler
相关联:
JobDetail
:定义了一个特定的 Job。可以使用JobBuilder
API 构建JobDetail
实例。Calendar
Trigger
(触发器):定义何时触发特定的 Job。
默认情况下,使用内存中的 JobStore
。但是,如果应用程序中存在 DataSource
bean,并且配置了 spring.quartz.job-store-type
属性,则可以配置基于 JDBC 的存储库,如下所示:
spring.quartz.job-store-type=jdbc
当使用 JDBC 存储库时,可以在启动时初始化模式(schema ),如下所示:
spring.quartz.jdbc.initialize-schema=always
注意:默认情况下,数据库是通过使用 Quartz 库提供的标准脚本来检测和初始化的。这些脚本会删除现有表,并在每次重启时删除所有触发器。还可以通过设置 spring.quartz.jdbc.schema
属性来提供自定义脚本。
要让 Quartz 使用除应用程序的主 DataSource
之外的其它 DataSource
,请声明一个 DataSource
bean,并将其 @Bean
方法用 @QuartzDataSource
注解。这样做可以确保 SchedulerFactoryBean
和模式初始化都使用 Quartz 特定的 DataSource
。同样,要让 Quartz 使用除应用程序的主 TransactionManager
之外的其它 TransactionManager
,请声明一个 TransactionManager
bean,并将其 @Bean
方法用 @QuartzTransactionManager
注解。
默认情况下,通过配置创建的job不会覆盖从持久job存储中读取的已注册job。要启用覆盖现有job定义,请设置 spring.quartz.overwrite-existing-jobs
属性。
Quartz Scheduler 的配置可以通过使用 spring.quartz
属性和 SchedulerFactoryBeanCustomizer
bean 进行自定义,这些 bean 允许对 SchedulerFactoryBean
进行编程式自定义。高级 Quartz 配置属性可以通过使用 spring.quartz.properties.*
进行自定义。
注意:特别是,Executor
bean 不与调度器关联,因为 Quartz 提供了一种通过 spring.quartz.properties
配置调度器的方法。如果需要自定义任务执行器,请考虑实现 SchedulerFactoryBeanCustomizer
。
作业可以定义 setter
方法来注入数据映射属性。常规 bean 也可以以类似的方式进行注入,如下所示:
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class MySampleJob extends QuartzJobBean {
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);
}
}