Quartz是一个开源的任务调度框架。作用是基于定时、定期的策略来执行任务。
它是OpenSymphony开源组织在Job scheduling领域又一个开源项目。
“任务进度管理器”就是一个在预先被纳入日程,当时间到达时,负责执行(或者通知)其他软件组件的系统。
简单来说就是实现“计划(或定时)任务”的系统,例如:订单下单后未付款,15分钟后自动撤消订单,并自动解锁锁定的商品。
官网:http://www.quartz-scheduler.org
参考:https://github.com/dufyun/quartz-core-learning
Quartz是一个任务调度框架。比如你遇到这样的问题:
在某一个有规律的时间点干某件事。
并且时间的触发的条件可以非常复杂(比如每月最后一个工作日的17:50),复杂到需要一个专门的框架来干这个事。Quartz就是来干这样的事,你给它一个触发条件的定义
,它负责到了时间点
,触发相应的Job
起来干活。<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-quartzartifactId>
dependency>
在主程序类上加@EnableScheduling
开启定时任务注解。
@SpringBootApplication
@MapperScan("com.example.mapper")
@EnableSwagger2
@EnableScheduling
public class SPApplication {
public static void main(String[] args) {
SpringApplication.run(SPApplication.class, args);
}
}
在application.yml的spring下添加:
quartz:
#相关属性配置
properties:
org:
quartz:
scheduler:
instanceName: DefaultQuartzScheduler
instanceId: AUTO
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
tablePrefix: QRTZ_
isClustered: false
clusterCheckinInterval: 10000
useProperties: true
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 10
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
#数据库方式
job-store-type: jdbc
#当spring关闭时,会等待所有已经启动的quartz job结束后spring才能完全shutdown
wait-for-jobs-to-complete-on-shutdown: true
任务一:
public class QMJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("任务一....");
}
}
任务二:
public class YRJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("任务二....");
}
}
项目中Quartz的数据库表由两部分组成:
第一部分:Quartz自带的11张表。
第二部分:项目中需要的任务记录表、任务参数表。
第一步:进入Quartz的官网: http://www.quartz-scheduler.org/,点击“Downloads”。
在“Downloads”页面下载相应的压缩包文件。
第二步:对下载的压缩包文件进行解压。
第三步:执行SQL脚本
在解压目录\src\org\quartz\impl\jdbcjobstore
下有常用数据库创建Quartz表的脚本:
根据项目使用的数据库软件,选择相应的.sql脚本执行。比如:MySQL数据库就使用tables_mysql.sql
。
将tables_mysql.sql导入运行,在数据库中生成11张表,如下:
需要两张业务表:
Id
Job_name
Job_group
Job_class
Job_descript
Job_cron
Job_status
Add_time
Update_time
爬取表:
Id
Job_id
Request_time
Job_data
第一步:创建任务记录表,并添加两条测试数据
Class c = Class.forName(“com.manubao.quartz.MyJob”)
任务记录表t_schedule_trigger:
#创建任务记录表
CREATE TABLE `t_schedule_trigger`(
`id` INT PRIMARY KEY AUTO_INCREMENT, #主键,标识列
`job_name` VARCHAR(100) NOT NULL UNIQUE, #任务名称
`job_group` VARCHAR(50) NOT NULL, #任务分组名称
`job_class` VARCHAR(200) NOT NULL, #任务类:填写Job类的完整类名
`job_desc` VARCHAR(200) NOT NULL, #任务描述
`cron` VARCHAR(100) NOT NULL, #Cron表达式
`trigger_name` VARCHAR(100) NOT NULL UNIQUE , #触发器名称
`trigger_group` VARCHAR(50) NOT NULL, #触发器分组名称
`trigger_desc` VARCHAR(200) NOT NULL, #触发器描述
`status` CHAR(1) NOT NULL, #状态:0禁用 1启用
`account` INT NOT NULL, #添加人:这里需要与用户表建立主外键关系
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP #添加时间
)ENGINE=INNODB DEFAULT CHARSET=utf8;
#添加数据
insert into t_schedule_trigger(
job_name, job_group, job_class, job_desc, cron, trigger_name, trigger_group, trigger_desc, status, account
) values
('愚人节的问候', '愚人组' , 'com.manubao.quartz.YRJob', '愚人节发个ILOVEYOU', '*/5 * * * * *', '愚人节触发器', 'trigger1', '触发器描述', 1, 1),
('中秋节的问候', '中秋组' , 'com.manubao.quartz.QmJob', '中秋节发个IMISSYOU', '*/7 * * * * *', '中秋节触发器', 'trigger1', '中秋节描述', 1, 1);
第二步:创建任务中的参数表(暂时不用)
#创建任务参数表
create table `t_schedule_trigger_param`(
`id` int primary key auto_increment, # ID
`name` varchar(200) not null, #参数名
`value` varchar(512), #参数值
`st_id` int not null references t_schedule_trigger(id) #外键:引用t_schedule_trigger(id)
);
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("t_schedule_trigger")
public class Trigger {
@TableId(value = "id", type = IdType.AUTO)
private Integer id; //主键,标识列
private String jobName; //任务名称
private String jobGroup; //任务分组名称
private String jobClass; //任务类:填写Job类的完整类名
private String jobDesc; //任务描述
private String cron; //Cron表达式
private String triggerName; //触发器名称
private String triggerGroup; //触发器分组名称
private String triggerDesc; //触发器描述
private int status; //状态:0禁用 1启用
private int account; //添加人
private Date createTime; //添加时间
}
@Mapper
public interface QuartzMapper extends BaseMapper<Trigger> {
}
接口:
public interface QuartzService extends IService<Trigger> {
//更新任务
void refreshTrigger();
}
实现类:
import javax.annotation.Resource;
import java.util.List;
@Service
public class QuartzServiceImpl extends ServiceImpl<QuartzMapper, Trigger> implements QuartzService {
@Resource
private QuartzMapper quartzMapper;
@Autowired
private Scheduler scheduler;
@Override
public void refreshTrigger() {
//获得所有的任务
List<Trigger> triggers = quartzMapper.selectList(null);
if( triggers != null){ //数据库中存在任务
for (Trigger trigger1 : triggers) {
//System.out.println(trigger);
if(trigger1.getStatus() == 1) { //1表示正常启用
//拿出一个任务,启动一个任务
try {
//1.定义JobDetail,将HelloJob类添加到JobDetail对象中(添加到Job清单)
//com.example.job.YRJob
JobDetail jobDetail = JobBuilder.newJob((Class<? extends Job>) Class.forName(trigger1.getJobClass()))
//任务的名字和组的名字(坑)
//任务名字不能相同
.withIdentity(trigger1.getJobName(), trigger1.getJobGroup())
.build();
//2.定义Trigger触发器,使用简单触发器,设置name/group
org.quartz.Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(trigger1.getTriggerName(), trigger1.getTriggerGroup())
.startNow()
.withSchedule(CronScheduleBuilder.cronSchedule(trigger1.getCron()))
.build();
//3.创建scheduler调度器
scheduler.scheduleJob(jobDetail, trigger);
//启动调度器
scheduler.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
}