# 11.3. Quartz 调度程序

Spring Boot 为使用[Quartz 调度程序](https://www.quartz-scheduler.org/)提供了多种便利，包括`spring-boot-starter-quartz`“Starter”。如果 Quartz 可用，则 `Scheduler`会自动配置（通过抽象的`SchedulerFactoryBean`）。

以下类型的 Bean 会自动选取并与`Scheduler` 相关联：

* `JobDetail`：定义特定的作业。可以使用`JobBuilder` API 构建 `JobDetail`实例。
* `Calendar`。
* `Trigger`：定义何时触发特定作业。

默认情况下，使用内存中的`JobStore`。但是，如果应用程序中存在可用的`DataSource` bean 并且相应配置了`spring.quartz.job-store-type`属性，则可以配置基于 JDBC 的存储，如以下示例所示：

```
spring.quartz.job-store-type=jdbc
```

当使用 JDBC 存储时，可以在启动时初始化架构，如以下示例所示：

```
spring.quartz.jdbc.initialize-schema=always
```

> 默认情况下，使用 Quartz 库提供的标准脚本检测并初始化数据库。这些脚本会删除现有表，并在每次重新启动时删除所有触发器。还可以通过设置`spring.quartz.jdbc.schema`属性来提供自定义脚本。

要让 Quartz 使用应用程序主数据源以外的数据源，请声明一个数据源 bean，并使用 `@QuartzDataSource`注释其`@Bean`方法。这样做可以确保 `SchedulerFactoryBean` 和模式初始化都使用 Quartz 特定的数据源。类似地，要让 Quartz 使用除应用程序的主 `TransactionManager` 之外的`TransactionManager`，请声明一个 `TransactionManager`bean，并使用 `@QuartzTransactionManager` 注释其`@Bean` 方法。

默认情况下，配置创建的作业不会覆盖从持久作业存储中读取的已注册作业。要启用覆盖现有作业定义，请设置`spring.quartz.overwrite-existing-jobs`属性。

Quartz Scheduler 配置可以使用`spring.quartz`属性和`SchedulerFactoryBeanCustomizer` bean进行定制，从而允许编程定制`SchedulerFactoryBean`。可以使用`spring.quartz.properties.*` 来定制高级 Quartz 配置属性。

> 特别是，`Executor`bean 不与调度程序关联，因为 Quartz 提供了一种通过`spring.quartz.properties`配置调度程序的方法。如果您需要自定义任务执行器，请考虑实现`SchedulerFactoryBeanCustomizer`.

作业可以定义设置器来注入数据映射属性。普通bean也可以通过类似的方式注入，如下例所示：

```
public class MySampleJob extends QuartzJobBean {
​
    // fields ...
​
    // 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);
    }
​
}
```
