Quartz 调度器
Spring Boot 针对 Quartz 调度器 提供了多项便利,包括 spring-boot-starter-quartz
启动器。
如果 Quartz 可用,会自动配置 Scheduler
(通过 SchedulerFactoryBean
抽象)。
以下类型的 bean 会被自动关联到 Scheduler
:
-
JobDetail
:定义特定 Job。JobDetail
实例可通过JobBuilder
API 构建。 -
Trigger
:定义 Job 触发时机。
默认使用内存型 JobStore
。
但如果应用中存在 DataSource
bean,并且配置了 spring.quartz.job-store-type
属性,也可配置为基于 JDBC 的存储,如下所示:
-
Properties
-
YAML
spring.quartz.job-store-type=jdbc
spring:
quartz:
job-store-type: "jdbc"
使用 JDBC 存储时,可在启动时初始化表结构,如下所示:
-
Properties
-
YAML
spring.quartz.jdbc.initialize-schema=always
spring:
quartz:
jdbc:
initialize-schema: "always"
默认情况下,数据库会使用 Quartz 库自带的标准脚本进行检测和初始化。
这些脚本会删除已有表,每次重启都会清空所有触发器。
如需自定义脚本,请设置 spring.quartz.jdbc.schema 属性。
部分标准脚本(如 SQL Server、Azure SQL、Sybase)需修改后方可使用。
此时请复制脚本并按注释修改,然后通过 spring.quartz.jdbc.schema 指定自定义脚本。
|
如需让 Quartz 使用应用主 DataSource
以外的数据源,请声明 DataSource
bean,并在其 @Bean
方法上添加 @QuartzDataSource
注解。
这样,Quartz 专用的数据源会被 SchedulerFactoryBean
和表结构初始化共同使用。
同理,如需让 Quartz 使用主 TransactionManager
以外的事务管理器,请声明 TransactionManager
bean,并在其 @Bean
方法上添加 @QuartzTransactionManager
注解。
默认情况下,通过配置创建的作业不会覆盖已从持久化作业存储读取的已注册作业。
如需允许覆盖现有作业定义,请设置 spring.quartz.overwrite-existing-jobs
属性。
Quartz 调度器配置可通过 spring.quartz
属性和 SchedulerFactoryBeanCustomizer
bean 进行定制,允许以编程方式自定义 SchedulerFactoryBean
。
高级 Quartz 配置属性可通过 spring.quartz.properties.*
定制。
特别说明,调度器默认不会关联 Executor bean,因为 Quartz 可通过 spring.quartz.properties 进行相关配置。
如需自定义任务执行器,可实现 SchedulerFactoryBeanCustomizer 。
|
作业可定义 setter 方法以注入数据映射属性。 常规 bean 也可类似注入,如下所示:
-
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)
}
}