开篇
这篇只介绍怎么用,不说原理;
先说一种常用的定时任务的方法;
使用schedule
定时任务最常用的是使用Springboot自带schedule;
使用springboot自带的schedule实现定时任务,不用引用任何第三方的工具包,只需要:
- 在启动类上增加@EnableScheduling注解,即可开启定时任务的支持;
- 定义自己的定时任务业务逻辑类 加上注解@Component或@Configuration,在定时任务的具体逻辑方法加上注解@Schedule("${cron表达式}")
使用Quratz:
Quartz 是一个完全由 Java 编写的开源作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。
Quartz 可以与 J2EE 与 J2SE 应用程序相结合也可以单独使用。
Quartz 允许程序开发人员根据时间的间隔来调度作业。
Quartz 实现了作业和触发器的多对多的关系,还能把多个作业与不同的触发器关联。
创建springboot工程:
在IDEA中基于springboot 2.7.*创建工程,集成Quratz,勾选I/O下Quratz Scheduler即可;
创建完成后的pom.xml主要内容:
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gz</groupId>
<artifactId>gz</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sz</name>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
上面Quratz的依赖是
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
创建一个Job
Job 表示一个工作,要执行的具体内容。
创建job时只需要继承QuratzJobBean,然后实现其中的executeInternal方法即可;
//Job类,触发定时任务后执行的操作
// QuartzJobBean是一个抽象类,实现了Quartz的Job接口。
//DisallowConcurrentExecution 禁止并发执行
@Component
@DisallowConcurrentExecution
public class PushJob extends QuartzJobBean {
ObjectMapper mapper = new ObjectMapper();
@PostConstruct
public void init(){
//每次运行都会加载一次
//System.out.println(System.currentTimeMillis()+"--pushJob-");
}
@Override
protected void executeInternal(JobExecutionContext context) {
System.out.println(System.currentTimeMillis()+"--push-");
try {
Thread.sleep(30000);
System.out.println("test");
System.out.println(mapper.writeValueAsString(context.getMergedJobDataMap()));
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
}
Job配置
创建JobConfiguration,注意添加注解Configuration;
在JobConfiguration中添加两个Bean
JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。
Trigger 代表一个调度参数的配置,什么时候去调。
还有一个Scheduler 代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler 容器调度了。
在Trigger中使用withSchedule方法加入调用队列;
@Configuration
public class JobConfiguration {
@Value("${quartz.push.cron:0/5 * * * * ?}")
private String restartCron; // corn表达式
@Bean
public JobDetail pushJobDetail(){
JobDetail jobDetail = JobBuilder.newJob(PushJob.class)
.withIdentity("pushJob")
.storeDurably()
.build();
return jobDetail;
};
@Bean
public Trigger pushJobTrigger(){
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
.cronSchedule(restartCron);
Trigger trigger = TriggerBuilder.newTrigger()
.forJob(pushJobDetail())
.usingJobData("type","studio")
.withIdentity("pushJobTrigger")
.withSchedule(scheduleBuilder)
.build();
return trigger;
}
}
后续只需要在Job中编码处理业务逻辑即可;
启动服务,即可看到Job中定时刷新功能;
关于注解DisallowConcurrentExecution
DisallowConcurrentExecution禁止并发执行多个相同定义的JobDetail,这个注解是加在Job类上的,但意思并不是不能同时执行多个Job, 而是不能并发执行同一个JobDefinition(由JobDetail定义)