Quartz入门和持久化
一:概述
Quartz是Java开发的,可以用作定时任务
功能相对于Timer更加强大 - 支持持久化
二:核心成员:
1.scheduler是一个计划调度器容器(总部),容器里面可以盛放众多的JobDetail和trigger,当容器启动后,里面的每个JobDetail都会根据trigger按部就班自动去执行。
2.JobDetail - 执行的内容
3.Trigger - 执行的时机/时间
4.当JobDetail和Trigger在scheduler容器上注册后/将Trigger和JobDetail交给scheduler之后,scheduler会自动再Trigger指定的时机自动去执行JobDetail
5.scheduler是个容器,容器中有一个线程池,用来并行调度执行每个作业,这样可以提高容器效率
相当于卧铺换票
乘务员 = schedule = 调度器
下车 = JobDetail = 作业
什么时候 = Trigger = 触发作业的机制【触发时间】
三:API介绍
JobDetail
Job - 是一个接口
作业
是一个接口,需要写一个自己的作业类去实现
JobDataMap
用于传递参数
Trigger
作业的触发机制或时间
分类:
SimpleTrigger
一般很少用
CronTrigger
CronExpressions
Cron表达式
不用自己写,百度有
Quartz入门和持久化
Quartz入门
1.导入包—pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
2.quartz的配置类QuartzConfig—quartz.config.QuartzConfig
@Configuration//这是一个配置类
public class QuartzConfig {
@Bean
public JobDetail newJob(){
return JobBuilder.newJob(PrintTimeJob.class)//PrintTimeJob我们的业务类
.withIdentity("9527")//可以给该JobDetail起一个id
//每个JobDetail内都有一个Map,包含了关联到这个Job的数据,在Job类中可以通过context获取
.usingJobData("msg", "Hello Quartz")//关联键值对
.storeDurably()//即使没有Trigger关联时,也不需要删除该JobDetail - 做持久化
.build();
}
//添加定时任务
@Bean
public Trigger printTimeJobTrigger() {
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/1 * * * * ? ");
return TriggerBuilder.newTrigger()
.forJob(newJob())//关联上述的JobDetail
.withIdentity("quartzTaskService")//给Trigger起个名字
.withSchedule(cronScheduleBuilder)
.build();
}
}
3.编写入门业务类即作业类:
public class PrintTimeJob implements Job{
@Override
public void execute(JobExecutionContext context) throws JobExecutionException{
System.out.println(context.getJobDetail().getJobDataMap().get("msg"));
System.out.println("current time :"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(new Date()));
}
}
4.启动程序进行测试,看控制台输出
/**
* 启动类
*/
@SpringBootApplication //标识当前类是SpringBoot应用的启动类
public class AppApplication {
//使用启动类运行Spring项目
public static void main(String[] args){
SpringApplication.run(AppApplication.class,args);
}
}
注:Cron Expressions【Cron 表达式】
https://cron.qqe2.com/
二:Quartz持久化
引入:如果运行的中途断电了:之前的定时任务就没有了
只要是Spring项目一启动,那么就会通过@Configuration启动一个定时任务,再次运行又会启动一个,只不过没有持久化而已
1.新建数据库和表
要持久化就需要数据库
新建数据库:名称quartz和文档中配置的名称一致
导入sql - 百度云链接
2.再上面的基础之上再写一个配置类QuartzDataSourceConfig用于指定数据源
@Configuration//这是一个配置类
public class QuartzDataSourceConfig {
//主数据源
@Bean
@Primary //主数据库,指向pethome
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource(){
return DataSourceBuilder.create().build();
}
//为quartz创建一个自己数据源
@Bean
@QuartzDataSource //quartz数据源
@ConfigurationProperties(prefix = "spring.quartz.properties.org.quartz.datasource")
public DataSource quartzDataSource(){
return DataSourceBuilder.create().build();
}
}
3.yml配置文件参考文档将内容拷贝过来
server:
port: 8080
servlet:
context-path: /
spring:
datasource:
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
jdbcUrl: jdbc:mysql:///pethome
quartz: #从这里开始 与datasource对其
job-store-type: jdbc #持久化到数据库
properties:
org:
quartz:
datasource:
driver-class-name: com.mysql.jdbc.Driver
jdbcUrl: jdbc:mysql:///quartz?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username: root
password: 123456
scheduler:
instancName: clusteredScheduler
instanceId: AUTO
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate #StdJDBCDelegate说明支持集群
tablePrefix: QRTZ_
isClustered: true
clusterCheckinInterval: 1000
useProperties: false
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 20
threadPriority: 5
#千万注意:数据源的url要改成jdbcUrl
4.测试
没有QuartzDataSourceConfig这个配置类时
启动SpringBoot项目
看见控制台已经有定时任务在执行
然后关闭项目,并将配置类QuartzConfig的注解@Configuration注销
再次启动项目发现控制台没有启动任务
所以没有持久化
注意:这里测试一定要注释掉@Configuration,否则一启动会有创建一个定时任务
有QuartzDataSourceConfig这个配置类时
启动SpringBoot项目
看见控制台已经有定时任务在执行
然后关闭项目,并将配置类QuartzConfig的注解@Configuration注销
再次启动项目发现控制台任然有任务执行
因为选择了数据源做了持久化
而且数据库表中有数据了
注意1:这里测试一定要注释掉@Configuration,否则一启动会有创建一个定时任务
注意2:如何清空之前的定时任务,因为持久化之后还是会出来。直接清空表即可。
但是要注意清空表时先清空除了qrtz_job_details的其他表,然后再清空qrtz_job_details表,外键关联。一起清空会失败