前言
Quartz是一个完全由java编写的开源作业调度框架,由OpenSymphony组织开源出来。所谓作业调度其实就是按照程序的设定,某一时刻或者时间间隔去执行某个代码。
quartz所需依赖
如果是已经有项目的就可以直接copy下面的放到pom.xml中
pom.xml
<!--解决spring中不能用切面的问题-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<!--quartz两个包-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
如果是新创项目的就创建的时候勾选就行
quartz详细讲解
本人先放代码后在讲解
流程图:
myjob.java
package com.liwangwang.quartz01.job;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @authorliwangwang
* @site www.liwangwang.com
* @company xxx公司
* @create 2019-11-14 21:13
*/
public class myjob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.err.println("这里开始执行我的任务.....");
Object t1 = context.getTrigger().getJobDataMap().get("t1");
Object t2 = context.getTrigger().getJobDataMap().get("t2");
Object j1 = context.getJobDetail().getJobDataMap().get("j1");
Object j2 = context.getJobDetail().getJobDataMap().get("j2");
Object scheduler=null;
try {
scheduler = context.getScheduler().getContext().get("scheduler");
} catch (SchedulerException e) {
e.printStackTrace();
}
System.out.println("t1:"+t1);
System.out.println("t2:"+t2);
System.out.println("j1:"+j1);
System.out.println("j2:"+j2);
System.out.println("scheduler:"+scheduler);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:hh:ss");
System.err.println("执行时间:"+ sdf.format(new Date()));
}
}
demo
package com.liwangwang.quartz01.Demo;
import com.liwangwang.quartz01.job.myjob;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
/**
* @authorliwangwang
* @site www.liwangwang.com
* @company xxx公司
* @create 2019-11-14 21:15
*/
public class demo2 {
public static void main(String[] args) throws SchedulerException {//这里仅仅只是模拟什么时候启动了这个触发器
//1,使用Scheduler工厂生成一个Scheduler
StdSchedulerFactory stdSchedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = stdSchedulerFactory.getScheduler();
scheduler.getContext().put("scheduler","scheduler");
//2.定义规则
Trigger trigger = (Trigger) TriggerBuilder.newTrigger()
//SimpleScheduleBuilder方法
// .withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(3,6))
//定时执行逻辑
// .withSchedule(CronScheduleBuilder.cronSchedule("0 45 4 * * ?"))
//死循环执行
.withSchedule(CronScheduleBuilder.cronSchedule("0/6 * * * * ?"))
.withIdentity("trigger1","Gtrigger1")
.withDescription("这是给demo1的一个触发器")
.usingJobData("t1","t1")
.build();
trigger.getJobDataMap().put("t2","t2");
//3.给任务定义属性(需要知道调用的是那个任务)
JobDetail jobDetail = (JobDetail) JobBuilder.newJob(myjob.class)
.withIdentity("jobDetail1","GjobDetail1")
.withDescription("这是为使用这个任务的一个描述")
.usingJobData("j1","j1")
.build();
jobDetail.getJobDataMap().put("j2","j2");
//4.把定义好了的触发器和任务交给Scheduler管理
scheduler.scheduleJob(jobDetail, trigger);
//5.开启任务
scheduler.start();
}
}
-
Scheduler的见解
Scheduler就是用来管理Trigger和JobDetail的,我们都可以看到在实列化一个Trigger或一个JobDetail后都是需要在Scheduler里进行一个注册,写好你这个Trigger或JobDetail的名字和组名都是需要用来区分开每一个Trigger的关键。
一个Trigger只能对应一个JobDetail,而一个JobDetail可以对应多个Trigger。这个应该还好理解,简单的说一个触发器只能触发一个任务,而任务可以被多个触发器所触发。
Scheduler是由SchdulerFactory创建,它有两个实现:DirectSchedulerFactory和 StdSchdulerFactory。前者可以用来在代码里定制你自己的Schduler参数。后者是直接读取classpath下的quartz.properties(不存在就都使用默认值)配置来实例化Schduler。通常来讲,我们使用StdSchdulerFactory也就足够了
-
Trigger的见解
总的说就是你打算怎么定义刷新时间滴。
定义有两种方式:第一种,由SimpleScheduleBuilder去用参数去定义、第二种,有一个特殊的语法cron语法去定义时长。 -
JobDetail的见解
可以这样理解,一个任务是一个实体,我有很多个任务,但是我在主线程中却不知道执行那个任务,这个时候就需要一个类(JobDetail)来详细定义你到底是想使用那个任务,比如我要使用myjob任务
JobDetail jobDetail = (jobDetail)newJob(myjob.class)
其实就是通过反射机制来确认是那个任务 -
Trigger和jobDetail的相同与不同
相同:
Trigger,jobDetail,两个都可以定义的规则
Identity,(id可以说是唯一标识)
Description,(描述)
usingJobData(就是一个键值对)
.withIdentity(“jobDetail1”,“GjobDetail1”)
.withDescription(“这是为使用这个任务的一个描述”)
.usingJobData(“j1”,“j1”)
不同:
Trigger,可以多定义的规则
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(3,6))
//定时执行逻辑
.withSchedule(CronScheduleBuilder.cronSchedule(“0 45 4 * * ?”))
//死循环执行
.withSchedule(CronScheduleBuilder.cronSchedule(“0/6 * * * * ?”)) -
job
这个就是写你要执行的任务代码就行。不过要实现job接口就行,这是Quartz的一个特点,非常容易上手
cron语法在线生成表达式网址:http://cron.qqe2.com/
springtask和quartz对比
quartz的总体代码都已放到了上面,所以就不多放了
放下springtask的代码:
package com.liwangwang.quartz01.Demo;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @authorliwangwang
* @site www.liwangwang.com
* @company xxx公司
* @create 2019-11-14 22:47
*/
@Service
public class springTask {
@Scheduled(cron = "0/10 * * * * ?")
public void job(){
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.err.println(format.format(new Date())+" : 这是一个spring task...");
try {
Thread.sleep(20*1000);
System.out.println("模拟正在处理大数据....");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
没错代码就这么简单
Spring task
优点:无需整合spring,作业类中就可以调用业务service
缺点:单线程;不能做数据存储型的定时任务
Quartz
优点:多线程;可以做数据存储型的定时任务,维护性高;
缺点:需要整合spring,不能直接调用业务层service;
还是简单的说各有各的优点。