定时任务
本文的架构如图
springboot内置定时任务
使用springboot内置的定时任务,具体的代码步骤:
1.导入依赖,任何的springboot依赖都可以
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
2.启动类上添加注解 @EnableScheduling
@EnableScheduling //这是springboot内置的定时任务的启动注解
@SpringBootApplication
public class QuartzSrpingboot1Application {
public static void main(String[] args) {
SpringApplication.run(QuartzSrpingboot1Application.class, args);
}
}
3.编写具体的定时任务执行的方法
使用注解:@Scheduled(cron = “1/5 * * * * ?”)
@Component
public class MyscheduleJob {
@Scheduled(cron = "1/5 * * * * ?")
public void doSchedule1(){
System.out.println("定时任务doSchedule1执行了!!");
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()).toString());
}
}
quartz定时任务
Quartz有四个核心概念:
- Job:是一个接口,只定义一个方法 execute(JobExecutionContext context),在实现接口的 execute方法中编写所需要定时执行的 Job(任务),JobExecutionContext 类提供了调度应用的一些信息;Job 运行时的信息保存在JobDataMap 实例中。
- JobDetail:Quartz 每次调度 Job 时,都重新创建一个 Job 实例,因此它不接受一个 Job 的实例,相反它接收一个Job 实现类JobDetail,描述 Job 的实现类及其他相关的静态信息,如 Job 名字、描述、关联监听器等信息),以便运行时通过newInstance() 的反射机制实例化 Job。
- trigger:是一个类,描述触发 Job 执行的时间触发规则,主要有 SimpleTrigger 和 CronTrigger这两个子类。当且仅当需调度一次或者以固定时间间隔周期执行调度,SimpleTrigger 是最适合的选择;而 CronTrigger则可以通过 Cron 表达式定义出各种复杂时间规则的调度方案:如工作日周一到周五的 15:00 ~ 16:00 执行调度等。
- Scheduler:调度器就相当于一个容器,装载着任务和触发器,该类是一个接口,代表一个 Quartz 的独立运行容器,Trigger 和JobDetail 可以注册到 Scheduler 中,两者在 Scheduler 中拥有各自的组及名称,组及名称是 Scheduler查找定位容器中某一对象的依据,Trigger 的组及名称必须唯一,JobDetail 的组和名称也必须唯一(但可以和 Trigger的组和名称相同,因为它们是不同类型的)。Scheduler 定义了多个接口方法,允许外部通过组及名称访问和控制容器中 Trigger h和JobDetail。
一.单独使用定时任务
1.导入依赖
<!--quartz核心包 -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
<!-- quartz工具包 -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.3.2</version>
</dependency>
2.自定义job类
package com.quartz.job;
import lombok.Data;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author gl
* @time 2020-05-02 15:44
* @function :演示job对象的基本操作,怎样获取jobDetail和trigger中的参数值等
* @step :
*/
@Data
public class JobDemo1 implements Job {
private String jobDetailParam;
private String triggerParam;
public JobDemo1(){
System.out.println("创建JobDemo1咯");
}
public void execute(JobExecutionContext context) throws JobExecutionException {
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = simpleDateFormat.format(date);
System.out.println("当前时间是:" + dateString);
//咱们的job中可以获取前面jobDetail传递过来的参数
System.out.println("jobDetail的名字:" + context.getJobDetail().getKey().getName());
System.out.println("jobDetail的group:" + context.getJobDetail().getKey().getGroup());
System.out.println("jobDetail的简单类名:" + context.getJobDetail().getJobClass().getSimpleName());
//获取jobDetail中的参数
//方法一:通过context对象
System.out.println("jobDetail存放的参数:" + context.getJobDetail().getJobDataMap().getString("jobDetailParam"));
//方法二:传递参数的时候因为本job有个名字一模一样的成员变量,则会把值赋值到该属性上
System.out.println("方法二:属性变量中获取jobDetail存放的参数:" + jobDetailParam);
//获取trigger中的对象
System.out.println("trigger的name:" + context.getTrigger().getKey().getName());
System.out.println("trigger的group:" + context.getTrigger().getKey().getGroup());
System.out.println("任务的开始时间:" + simpleDateFormat.format(context.getTrigger().getStartTime()));
//System.out.println("任务的结束时间:" + simpleDateFormat.format(context.getTrigger().getEndTime()));因为结束时间为null,所以会报错
//获取trigger中存放的参数
//方法一:通过context对象化获取trigger参数
System.out.println("trigger中存放的参数:" + context.getTrigger().getJobDataMap().getString("triggerParam"));
//方法二:传递参数的时候因为本job有个名字一模一样的成员变量,则会把值赋值到该属性上
System.out.println("方法二:属性变量中获取trigger存放的参数:" + triggerParam);
}
}
3.运行本job
代码步骤:
1.创建schedule对象
2.创建jobDetail对象
3.创建trigger对象
4.schedule关联trigger对象和jobDetail对象,并且启动schedule
package com.quartz.job;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
/**
* @author gl
* @time 2020-05-02 15:46
* @function : 启动一个job
* @step :
* 1.创建schedule对象
* 2.创建jobDetail对象
* 3.创建trigger对象
* 4.schedule关联trigger对象和jobDetail对象,并且启动schedule
*/
public class JobTest1 {
public static void main(String[] args) throws SchedulerException {
//1.获取scheduler调度器对象,这里是默认的调度器对象
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//2.获取job的实例对象jobdetail
JobDetail jobDetail = JobBuilder.newJob(JobDemo1.class)
//jobDemo1代表的实例名字,grop1代表的所属的任务组,组名参数可以没有,默认是default组下的
.withIdentity("jobDemo1", "grop1")
//向创建的job实例对象中传递参数,如果该参数的key是job的成员属性,则会自动赋值到成员属性上.
.usingJobData("jobDetailParam","jobDetail中存放的参数值")
.build();
System.out.println("job实例的名称:" + jobDetail.getKey().getName());
System.out.println("job的组Group的名称:" + jobDetail.getKey().getGroup());
System.out.println("job的类型:" + jobDetail.getJobClass().getName());
//3.获取trigger对象
SimpleTrigger trigger = TriggerBuilder.newTrigger()
.withIdentity("triggerDemo1", "triggerGrop")
.usingJobData("triggerParam","trigger中存放的参数值")//向trigger中存放参数
.startNow()//马上启动触发器
.withSchedule(
SimpleScheduleBuilder
.simpleSchedule() //获取simpleSchedule对象
.withIntervalInSeconds(5) //每隔5秒执行一次
//.repeatForever() //一直执行
.withRepeatCount(2)//总共执行三次
)//用simpleSchedule
.build();
//4.让调度器去关联trigger和job,并且启动schedule
scheduler.scheduleJob(jobDetail,trigger); //关联jobdetai和trigger
scheduler.start(); //启动调度器schedule
}
}
二.springboot-quartz
springboot整合quartz,因为我们单独使用quartz的时候是利用main方法的入口执行的quartz.但是如果我们利用springboot整合quartz,则不能利用main方法入口执行了.
1.导入依赖
<!--添加Quartz的支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
package com.gl.quartzsrpingboot1.quartz;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author gl
* @time 2020-05-06 10:55
* @function : 这是quartz的自定义job类
* @step :
*/
public class QuartzJob1 extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()).toString() + "自定义QuartzJob1,定时任务执行了!!");
}
}
3.配置quartz的配置类
package com.gl.quartzsrpingboot1.quartz;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author gl
* @time 2020-05-06 10:57
* @function :
* @step :
*/
@Configuration //本注解一定要加
public class QuartzConfig1 {
/**
* 这是定义job的实例化对象
* @return
*/
@Bean //本注解一定要加,代表将jobDetail注入到spring的容器中
public JobDetail getJobDetail(){
JobDetail jobDetail = JobBuilder.newJob(QuartzJob1.class)
.withIdentity("QuartzJob1") //job名称
.usingJobData("username", "古龙") //job的参数
.usingJobData("password", "123456") //job的参数
.withDescription("这是测试jobDetail1") //job的描述
.storeDurably() //
.build();
return jobDetail;
}
/**
* jobDetail的trigger对象
* @return
*/
@Bean //本注解一定要加,代表将jobDetail注入到spring的容器中
public Trigger getTrigger(){
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
CronTrigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.usingJobData("age", 10)
.withSchedule(cronScheduleBuilder)
.forJob(getJobDetail()) //这里不能省略,一定要关联上job
.build();
return trigger;
}
}
如果想要将quartz持久化到数据库,请自定义quartz.properties