SpringBoot 定时任务+Quartz

前言:

1、定时任务技术:

  • JDK 的 Timer, 定义多个定时任务,其中某个任务出现异常,当时整个定时任务终止。
  • Spring Task , 不支持 持久化与分布式部署,所有任务是单线程执行的
  • Quartz,支持持久化多线程执行。

2、Spring Boot 整合Quartz

  • Job: 任务。定时执行的具体任务内容
  • JobDetail: 任务详情。即与任务相关的其他配置信息
  • Trigger: 触发器,主要负责描述任务执行的时间规则
  • Scheduler: 调度器。
  • 将Job和Trigger整合起来之间的关系: Job:JobDetail->1:N JobDetail:Trigger->1:N Trigger:JobDetail->1:1

3、引入pom文件:

javascript 复制代码
 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
 </dependency>

4、创建执行任务,Job (自己的定时任务)

对应代码:

javascript 复制代码
@Slf4j
@DisallowConcurrentExecution
@PersistJobDataAfterExecution
public class MyJob extends QuartzJobBean {
    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        System.out.println("任务开始执行");
        JobDetail jobDetail = context.getJobDetail();
        System.out.println("名字" + jobDetail.getKey().getName());
        System.out.println("类名--->" + jobDetail.getJobClass().getName());
        System.out.println("本次执行的时间为---》" + context.getFireTime());
        System.out.println("下次执行的时间为---》" + context.getNextFireTime());
        System.out.println("任务执行完毕");
        System.out.println("============================");
    }
} 

5、创建JobDtail 和 Trigger


在执行任务的类上添加注解。

  • PersistJobDataAfterExecution ,有状态的,在定时任务执行的Job中获取的JobExecutionContext 是同一个。比如在JobDetail 中,usingJobData("count",1);进行共享数据的初始化,如果不使用这个注解在执行任务上,会获取不同的JobExecutionContext 。
  • DisallowConcurrentExecution 在时间间隔内,如果本任务没有执行完成,下一个任务不会启动,一直到本任务结束。下一个任务才开始执行。

创建配置类:


解释:

持久化 .storeDurably() 。如果没有持久化,没有对应的触发器,失去执行的条件,存在没有意义,就会将其删除。

如果有持久化,没有对应的触发器,还是会保留 JobDetail。

对应代码:

javascript 复制代码
@Configuration
public class QuartzConfiguration {

    //JobDetail
     @Bean(value = "jobDetail")
    public JobDetail jobDetail(){
    return JobBuilder.newJob(MyJob.class)
            .storeDurably()
            //唯一标识
            .withIdentity("jobDetail")
            .build();
    }
    @Bean
    // @Qualifier 引用指定的bean 的实例对象。
    public Trigger trigger(@Qualifier("jobDetail")JobDetail jobDetail){
        Trigger jobDetail1 = TriggerBuilder.newTrigger()
                .forJob(jobDetail)
                //唯一标识和上面的JobDetail是配对的。
                .withIdentity("jobDetail")
                //这个表达式可以写到yml 中进行引用,这样以后更改直接改配置文件即可。
                //每两秒钟执行一次
                .withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?"))
                .build();
        return jobDetail1;
    }

}

6、cron表达式

java 复制代码
tips:
  一般使用 六位,最后一位年 一般不使用。

整体代码实例演示:
pom文件

javascript 复制代码
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-quartz</artifactId>
    </dependency>

1、自己的定时任务Job

javascript 复制代码
@Slf4j
@DisallowConcurrentExecution
@PersistJobDataAfterExecution
public class MyJob extends QuartzJobBean {
    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        System.out.println("任务开始执行");
        JobDetail jobDetail = context.getJobDetail();
        System.out.println("名字" + jobDetail.getKey().getName());
        System.out.println("类名--->" + jobDetail.getJobClass().getName());
        System.out.println("本次执行的时间为---》" + context.getFireTime());
        System.out.println("下次执行的时间为---》" + context.getNextFireTime());
        System.out.println("任务执行完毕");
        System.out.println("============================");
    }
} 

2、定时任务的配置类

javascript 复制代码
@Configuration
public class QuartzConfiguration {

    //JobDetail
     @Bean(value = "jobDetail")
    public JobDetail jobDetail(){
    return JobBuilder.newJob(MyJob.class)
            .storeDurably()
            //唯一标识
            .withIdentity("jobDetail")
            .build();
    }
    @Bean
    //Trigger
    public Trigger trigger(@Qualifier("jobDetail")JobDetail jobDetail){
        Trigger jobDetail1 = TriggerBuilder.newTrigger()
                .forJob(jobDetail)
                //唯一标识和上面的JobDetail是配对的。
                .withIdentity("jobDetail")
                //这个表达式可以写到yml 中进行引用,这样以后更改直接改配置文件即可。
                //每两秒钟执行一次
                .withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?"))
                .build();
        return jobDetail1;
    }

}
相关推荐
长谷深风1114 小时前
Agent执行系统中的身份与版本设计
java·大数据·人工智能·ai·大模型·task·aiagent
Wang's Blog4 小时前
Java框架快速入门: Spring Security+OAuth2之UserDetails与JDBC认证实践
java·网络·spring
爱从未走散4 小时前
面试八股题
java·面试·职场和发展
艺杯羹4 小时前
AI编程时代软件工程怎么学:从底层思维认知到驱动智能体的架构跃迁
java·人工智能·ai·架构·软件工程·ai编程
土司大王4 小时前
LeetCode hot100——51.N 皇后:Java 回溯模板、列与对角线剪枝、O(n!) 复杂度分析
java·leetcode·剪枝
码外生活4 小时前
🎥 手搓一套直播高并发环境!一个后端小白从 0 到 1 的搭建笔记
后端·spring cloud
重生之小比特4 小时前
【Java SE】IDEA 调试 Debug 案例完整分析
java·ide·intellij-idea
晴天164 小时前
JavaScript 与 Java 垃圾回收机制对比
java·开发语言·javascript
Lyra_Infra4 小时前
记一次麒麟 Linux 下达梦数据库 (DM8) 部署与 MySQL 命令行无界面迁移踩坑指南
数据库·后端·dba
Daemonkey4 小时前
苦 Elasticsearch/Prometheus 久矣?试试 Rust 打造的云原生可观测新星:OpenObserve
后端