springboot2.x支持对quartz的自动配置,引入jar
<!-- spring boot2.x + quartz -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
数据库建表
到官网上下载最新quartz版本,在docs\dbTables文件目录下找到建表sql脚本
quartz集群相关配置
springboot会读取yml文件内容并将值组装到QuartzProperties类中
spring:
quartz:
job-store-type: jdbc #数据库方式
jdbc:
initialize-schema: never #不初始化表结构
properties:
org:
quartz:
scheduler:
instanceId: AUTO #默认主机名和时间戳生成实例ID,可以是任何字符串,但对于所有调度程序来说,必须是唯一的 对应qrtz_scheduler_state INSTANCE_NAME字段
#instanceName: clusteredScheduler #quartzScheduler
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX #持久化配置
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate #我们仅为数据库制作了特定于数据库的代理
useProperties: true #以指示JDBCJobStore将JobDataMaps中的所有值都作为字符串,因此可以作为名称 - 值对存储而不是在BLOB列中以其序列化形式存储更多复杂的对象。从长远来看,这是更安全的,因为您避免了将非String类序列化为BLOB的类版本问题。
tablePrefix: qrtz_ #数据库表前缀
misfireThreshold: 60000 #在被认为“失火”之前,调度程序将“容忍”一个Triggers将其下一个启动时间通过的毫秒数。默认值(如果您在配置中未输入此属性)为60000(60秒)。
clusterCheckinInterval: 5000 #设置此实例“检入”*与群集的其他实例的频率(以毫秒为单位)。影响检测失败实例的速度。
isClustered: true #打开群集功能
threadPool: #连接池
class: org.quartz.simpl.SimpleThreadPool
threadCount: 10
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
注意:本文版本2.0.4,随着版本迭代。属性参数会有变化。如下为2.1.0版本官网文档说明
# QUARTZ SCHEDULER (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.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.job-store-type=memory # Quartz job store type.
spring.quartz.overwrite-existing-jobs=false # Whether configured jobs should overwrite existing job definitions.
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.wait-for-jobs-to-complete-on-shutdown=false # Whether to wait for running jobs to complete on shutdown.
扩展SchedulerFactoryBean
SpringBoot的QuartzAutoConfiguration类会帮我自动配置SchedulerFactoryBean。使用SpringBoot提供的SchedulerFactoryBeanCustomizer接口去扩展SchedulerFactoryBean。
@Component
public class MySchedulerFactoryBean implements SchedulerFactoryBeanCustomizer {
@Override
public void customize(SchedulerFactoryBean schedulerFactoryBean) {
schedulerFactoryBean.setOverwriteExistingJobs(true);//更新trigger的 表达式时,同步数据到数据库qrtz_cron_triggers表 开启
schedulerFactoryBean.setApplicationContextSchedulerContextKey("applicationContext");//注入applicationContext
//to do
}
}
定义JobDetail和Trigger
springboot自动把Trigger注入schedulerFactoryBean中
@Configuration
public class QuartzConfig {
/**
* 定义JobDetail 直接使用 jobDetailFactoryBean.getObject 获得的是空
* @return
*/
@Bean
public JobDetailFactoryBean printTimeJobDetail(){
JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
// durability 表示任务完成之后是否依然保留到数据库,默认falses
jobDetailFactoryBean.setDurability(true);
//当Quartz服务被中止后,再次启动或集群中其他机器接手任务时会尝试恢复执行之前未完成的所有任务
jobDetailFactoryBean.setRequestsRecovery(true);
jobDetailFactoryBean.setJobClass(MyDetailQuartzJobBean.class);
jobDetailFactoryBean.setDescription("打印时间定时器2");
Map<String,String> jobDataAsMap = new HashMap<>();
jobDataAsMap.put("targetObject","printTimeQuartz"); //spring 中bean的名字
jobDataAsMap.put("targetMethod","execute"); //执行方法名
jobDetailFactoryBean.setJobDataAsMap(jobDataAsMap);
return jobDetailFactoryBean;
}
/**
* 定义一个Trigger
* @return
*/
@Bean
public CronTriggerFactoryBean printTimeCronTrigger(JobDetail printTimeJobDetail){
CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
// 设置jobDetail
cronTriggerFactoryBean.setJobDetail(printTimeJobDetail);
//秒 分 小时 日 月 星期 年 每10分钟
cronTriggerFactoryBean.setCronExpression("0 0/10 * * * ?");
//trigger超时处理策略 默认1:总是会执行头一次 2:不处理
cronTriggerFactoryBean.setMisfireInstruction(2);
return cronTriggerFactoryBean;
}
}
JobClass
public class MyDetailQuartzJobBean extends QuartzJobBean {
private Logger logger = LoggerFactory.getLogger(MyDetailQuartzJobBean.class);
/**
* 目标对象
*/
private String targetObject;
/**
* 执行的方法
*/
private String targetMethod;
/**
* spring 上下文对象
*/
private ApplicationContext ctx;
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
try {
logger.info("execute [" + targetObject + "] at once>>>>>>");
Object otargetObject = ctx.getBean(targetObject);
Method m = otargetObject.getClass().getMethod(targetMethod, new Class[] {});
m.invoke(otargetObject, new Object[]{});
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
public void setApplicationContext(ApplicationContext applicationContext) {
this.ctx = applicationContext;
}
public void setTargetObject(String targetObject) {
this.targetObject = targetObject;
}
public void setTargetMethod(String targetMethod) {
this.targetMethod = targetMethod;
}
}
打印日志如下
2018-10-31 14:50:00.105 INFO 24156 --- [eduler_Worker-1] c.t.m.task.utils.MyDetailQuartzJobBean : execute [printTimeQuartz] at once>>>>>>
2018-10-31 14:50:00.105 INFO 24156 --- [eduler_Worker-1] c.test.mspringboot.task.PrintTimeQuartz : Quartz PrintTimeQuartz.execute()... : Current time is :2018-10-31 14:50:00
2018-10-31 15:00:00.184 INFO 24156 --- [eduler_Worker-2] c.t.m.task.utils.MyDetailQuartzJobBean : execute [printTimeQuartz] at once>>>>>>
2018-10-31 15:00:00.186 INFO 24156 --- [eduler_Worker-2] c.test.mspringboot.task.PrintTimeQuartz : Quartz PrintTimeQuartz.execute()... : Current time is :2018-10-31 15:00:00
2018-10-31 15:10:00.076 INFO 24156 --- [eduler_Worker-3] c.t.m.task.utils.MyDetailQuartzJobBean : execute [printTimeQuartz] at once>>>>>>
自动配置类说明
1.AutowireCapableBeanJobFactory
替代了使用springmvc时,继承SpringBeanJobFactory的子类实现,主要作用是我们自定义的QuartzJobBean子类被Spring IOC进行托管,可以在定时任务类内使用注入任意被Spring IOC托管的类。
2.JobStoreType
该类是一个枚举类型,定义了对应application.yml、application.properties文件内spring.quartz.job-store-type配置,其目的是配置quartz任务的数据存储方式,分别为:MEMORY(内存方式:默认)、JDBC(数据库方式)。
3.QuartzAutoConfiguration
自动配置的主类,内部配置了SchedulerFactoryBean以及JdbcStoreTypeConfiguration,使用QuartzProperties作为属性自动化配置条件。
4.QuartzDataSourceInitializer
主要用于数据源初始化后的一些操作,根据不同平台类型的数据库进行选择不同的数据库脚本。
5.QuartzProperties
对应了spring.quartz在application.yml、application.properties文件内开头的相关配置。
6.SchedulerFactoryBeanCustomizer
一个接口,我们实现该接口后并且将实现类使用Spring IOC托管,可以完成SchedulerFactoryBean的个性化设置,这里的设置完全可以对SchedulerFactoryBean做出全部的设置变更。