SpringBoot + Quartz 实现定时任务

本文介绍如何在Spring Boot中使用@Scheduled和Quartz进行定时任务管理,包括依赖添加、定时任务编写及配置,展示不同触发方式的实现。

什么是定时任务?

定时任务是企业级开发中最常见的功能之一,如定时统计订单数量、数据库备份、定时发送短信和邮件、定时统计博客访问量等等

@Scheduled

简单的定时任务可以通过 Spring 中提供的 @Scheduled 注解来实现

@Scheduled 是由 Spring 提供的定时任务注解,使用方便,配置简单,可以解决工作中大部分的定时任务需求,使用方式如下:

添加依赖

只需添加 web 依赖即可

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

编写定时任务

package com.example.demo.config;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.Date;

@Component
public class MySchedule {

    /**
     * 表示在当前任务执行结束 1s 后开启另一个任务
     */
    @Scheduled(fixedDelay = 1000)
    public void fixedDelay() {
        System.out.println("fixedDelay : " + new Date());
    }

    /**
     * 表示在当前任务执行结束 2s 后开启另一个定时任务
     */
    @Scheduled(fixedRate = 2000)
    public void fixedRate() {
        System.out.println("fixedRate : " + new Date());
    }

    /**
     * initialDelay = 1000 表示首次执行的延迟时间
     */
    @Scheduled(initialDelay = 1000,fixedRate = 2000)
    public void initialDelay() {
        System.out.println("initialDelay : " + new Date());
    }

    /**
     * cron = "0 * * * * ?" 表示该定时任务每分钟执行一次
     */
    @Scheduled(cron = "0 * * * * ?")
    public void cron() {
        System.out.println("cron : " + new Date());
    }
}

开启定时任务

开启定时任务只需要在启动类加上 @EnableScheduling 注解即可

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling // 开启定时任务的注解
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class,args);
    }
}

输出:
在这里插入图片描述

Quartz

什么是 Quartz ?

Quartz 是一个功能丰富的开源作业调度库,它由 Java 编写而成,可以继承在任何 Java 的应用程序之中,包括 Java SE 和 Java EE 等等,使用 Quartz 可以创建简单或者复杂的执行计划,它支持数据库、集群、插件以及邮件,并且支持 cron 表达式,具有极高的灵活性。SpringBoot 中继承了 Quartz 和 Spring 中集成了 Quartz 比较类似,主要提供了三个 Bean:JobDetail、Trigger 以及 SchedulerFactory

添加依赖

添加 SpringBoot 整合 Quartz 的依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

创建任务

这里创建两个任务

package com.example.demo.config;

import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class FirstDemo {
    public void sayHello() {
        System.out.println("FirstDemo start at : " + new Date());
    }
}

FirstDemo 是一个普通的 JavaBean,如果是普通的 JavaBean,那么可以先添加 @Component 注解将其注册到 Spring 容器中。


package com.example.demo.config;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

import java.util.Date;

public class SecondDemo extends QuartzJobBean {

    private String name;

    public void setName(String name) {
        this.name = name;
    }

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("hello : " + name + " : " + new Date());
    }
}

SecondDemo 也可以继承抽象类 QuartzJobBean,如果继承 QuartzJobBean,则需要实现该类中的 executeInternal 方法,该方法在任务调用时使用

配置类

package com.example.demo.config;

import org.quartz.CronTrigger;
import org.quartz.JobDataMap;
import org.quartz.SimpleTrigger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.*;

@Configuration
public class QuartzConfig {

    /**
     * JobDetail 的配置方式有两种:
     * 第一种方式是通过 MethodInvokingJobDetailFactoryBean 类配置 JobDetail,
     * 只需要指定 Job 的实例名和要调用的方法即可,注册这种方式无法在创建 JobDetail 时传递参数
     *
     * 第二种方式是通过 JobDetailFactoryBean 来实现的,这种方式只需要指定 JobClass 即可,然后通过
     * JobDataMap 传递参数到 Job 中,Job 中只需要提供属性名,并且提供一个相应的 set 方法即可接收到参数
     * @return
     */
    @Bean
    public MethodInvokingJobDetailFactoryBean jobDetailFactoryBean() {
        MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
        bean.setTargetBeanName("firstDemo");
        bean.setTargetMethod("sayHello");
        return bean;
    }

    @Bean
    public JobDetailFactoryBean jobDetailFactoryBean2() {
        JobDetailFactoryBean bean = new JobDetailFactoryBean();
        bean.setJobClass(SecondDemo.class);
        JobDataMap jobDataMap = new JobDataMap();
        jobDataMap.put("name","John");
        bean.setJobDataMap(jobDataMap);
        bean.setDurability(true);
        return bean;
    }


    /**
     * Trigger 有多种不同的实现,这里分别使用 SimpleTrigger 和 CronTrigger
     * @return
     */


    /**
     * 在 SimpleTriggerFactoryBean 对象中,首先设置 JobDetail,然后通过 setRepeatCount 配置任务
     * 循环次数,setStartDelay 配置任务启动延迟时间,setRepeatInterval 配置任务的时间间隔
     * @return
     */
    @Bean
    public SimpleTriggerFactoryBean simpleTriggerFactoryBean() {
        SimpleTriggerFactoryBean bean = new SimpleTriggerFactoryBean();
        bean.setJobDetail(jobDetailFactoryBean().getObject());
        bean.setRepeatCount(3);
        bean.setStartDelay(1000);
        bean.setRepeatInterval(2000);
        return bean;
    }

    /**
     * 在 CronTriggerFactoryBean 对象中,则主要配置 JobDetail 和 Cron 表达式
     * @return
     */
    @Bean
    public CronTriggerFactoryBean cronTriggerFactoryBean() {
        CronTriggerFactoryBean bean = new CronTriggerFactoryBean();
        bean.setJobDetail(jobDetailFactoryBean2().getObject());
        bean.setCronExpression("* * * * * ?");
        return bean;
    }

    /**
     * 通过 SchedulerFactoryBean 创建 SchedulerFactory,然后配置 Trigger
     * @return
     */
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() {
        SchedulerFactoryBean bean = new SchedulerFactoryBean();
        SimpleTrigger simpleTrigger = simpleTriggerFactoryBean().getObject();
        CronTrigger cronTrigger = cronTriggerFactoryBean().getObject();
        bean.setTriggers(simpleTrigger,cronTrigger);
        return bean;
    }
}

启动定时任务

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class,args);
    }
}

输出:
在这里插入图片描述

模拟电子 Multisim仿真实 数字电子Multisim仿真实验Multisim仿真实例合集500例:0音调音频放大器.ms141-99分钟倒计时 (1).ms101.6KHz输出幅度可调四种波形发生器 (2).ms101.6KHz输出幅度可调四种波形发生器.ms10161210 交流接触器自锁互锁.ms10161212 555触摸延时.ms10161216 555多谐振荡喇叭应用.ms10161219 交通灯控制器设计(改).ms14161224 78XX增强型稳压输出电路.ms13161225 八路彩灯控制器.ms10170414 200KHz三角波3554.ms10170414 200KHz三角波5534.ms10170414 文氏振荡 5KHz ±5V.ms10170415 三种波形发生器 5kHz ±5V.ms10170417 LM723过流保护直流可调稳压电源.ms10170417 TDA2030音调音频放大器.ms10170621 自动打铃器(6组定时).ms10170622 三位数密码锁.ms10170624 速度表.ms12170709 交通信号灯 60(5) 45(5).ms13170923 彩灯控制器(部分).ms10171219 八位二进制转三位十进制.ms13171230 序列脉冲控制电子锁.ms10171230 序列脉冲控制电子锁.ms11171231 出租车自动计费器.ms10171231 出租车计费器.ms10180101 出租车计费器X等候过程错误计费问题】.ms10180119 过压欠压保护电路.ms10180307 MAX16823应用.ms10180423 信号发生器.ms105-12V+可调稳压电源电路(317).ms105-20V+可调稳压电源电路(317).ms1450-5-30 红绿灯控制电路 (2).ms1050-5-30 红绿灯控制电路.ms106路20秒声光显示计分抢答器.ms146路20秒声光显示计分抢答器.ms14 8位ADC应用-LM317 5-12调压显示.ms138路抢答器电路 (2).ms108路抢答器电路.ms10BCD应用BCD译码器.ms13Multisim仿真—电路&模电&数电.docMultisim模拟电路仿真实例.pptMultisim电路实例TL494 DC-DC应用.ms12三种波形发生器 (2).ms10三种波形发生器.ms10交通灯20-3-10-3 (2).ms10交通灯.ms10四种波形发生器-741 (2).ms10四种波形发生器-741.ms10四路20秒声光显示计分抢答器 (2).ms10四路20秒声光显示计分抢答器.ms10基于Multisim的高频信号发生器设计.doc定时3秒的蜂鸣器可预置的有点错的倒计时定时器.ms14小车灯光模拟器拔河游戏 (2).ms10拔河游戏.ms10数字日历设计 (2).ms10数字日历设计.ms10数字时钟电路带兴起显示.ms14数字时钟电路带兴起显示.ms14 (Security copy)数字电子仿真实验数字电子钟仿真电路图 (2).ms10数字电子钟仿真电路图.ms10数字跑表 (2).ms13数字跑表.ms13数码管的简单控制 (2).ms13数码管的简单控制.ms13模拟电子仿真实验正弦波741 (2).ms10正弦波741.ms10程控宽带放大器第1章应用举例第2章应用举例第3章应用举例第4章应用举例简易洗衣机2_X (2).ms10简易洗衣机2_X.ms10简易电梯 (2).ms13简易电梯.ms13篮球30秒计时器_X (2).ms13篮球30秒计时器_X.ms13负反馈式音调控制电路 (2).ms12负反馈式音调控制电路.ms12高频电路实验Multisim版1-52.doc
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值