2022/6/27 Quartz(定时任务)讲解+入门案例

目录

1丶Quartz简介

2丶Quartz运行环境

3丶Quartz设计模式

4丶Quartz学习的核心概念

        4.1丶任务Job

        4.2丶触发器Triger

        4.3丶调度器Scheduler

5丶Quartz的体系结构

6丶Quartz 的常用API

7丶CronExpression表达式

8丶快速开始(入门demo)

        8.1丶新建一个maven项目

        8.2丶 编写一个Job类

        8.3丶编写触发器和调度器

        8.4丶运行结果 

9丶SpringBoot 整合 Quartz

        9.1丶引入依赖

        9.2丶编写配置Quartz类 

                9.2.1丶MyAdaptableJobFactory

                9.2.2丶QuartzConfig

        9.3丶 编写QuartzService类

        9.4丶 启动器类

        9.5丶applicationyaml配置文件 

        9.6丶运行结果


1丶Quartz简介

官网Quartz Enterprise Job Scheduler

Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与2EE与|2SE应用程序相结合也可以单独使用。

quartz是开源且具有丰富特性的"任务调度库",能够集成于任何的java应用,小到独立的应用,大至电子商业系统。quartz能够创建亦简单亦复杂的调度,以执行上十、上百,甚至上万的任务。任务job被定义为标准的java组件,能够执行任何你想要实现的功能。quartz调度框架包含许多企业级的特性,如JTA事务、集群的支持。

简而言之,quartz就是基于java实现的任务调度框架,用于执行你想要执行的任何任务。

2丶Quartz运行环境

  • Quartz 可以运行嵌入在另一个独立式应用程序
  • Quartz 可以在应用程序服务器(或servlet容副内被实例化,并且参与事务)
  • Quartz 可以作为一个独立的程序运行(其自己的ava虚拟机内),可以通过RMI使用
  • Quartz 可以被实例化,作为独立的项目集群(负载平衡和故障转移功能),用于作业的执行

3丶Quartz设计模式

  • Builder模式
  • Factory模式
  • 组件模式  JobDetail   Trigger
  • 链式编程 

4丶Quartz学习的核心概念

        4.1丶任务Job

Job就是你想要实现的任务类,每一个Job必须实现org.quartz.job接口,且只需实现接口定义的execute()方法。

        4.2丶触发器Triger

Triger为你执行任务的触发器,比如你想每天定时3点发送一份统计邮件,Trigger将会设置3点进行执行该任务。Trigger主要包含两种SimpleTrigger和CronTrigger两种。关于二者的区别的使用场景,后续会进行讨论。

        4.3丶调度器Scheduler

Scheduler为任务的调度器,它会将任务job及触发器Trigger整合起来,负责基于Triggeri设定的时间来执行Job.

5丶Quartz的体系结构

6丶Quartz 的常用API

 以下是Quartz编程API几个重要接口,也是Quartz的重要组件

  • Scheduler 用于与调度程序交互的主程序接口。Scheduler 调度程序-任务执行计划表,只有安排进执行计划的任务Job(通过scheduler.scheduleJob方法安排进执行计划),当它预先定义的执行时间到了的时候(任务触发trigger),该任务才会执行。
  • Job 我们预先定义的希望在未来时间能被调度程序执行的任务类,我们可以自定义。
  • JobDetail使用JobDetail来定义定时任务的实例,JobDetail实例是通过JobBuilder类创建的。
  • JobDataMap 可以包含不限量的(序列化的)数据对象,在iob实例执行的时候,可以使用其中的数据;JobDataMap是Java Map接口的一个实现,额外增加了一些便于存取基本类型的数据的方法。
  • Trigger 触发器,Trigger对象是用来触发执行lob的。当调度一个job时,我们实例一个触发器然后调整它的属性来满足job执行的条件。表明任务在什么时候会执行。定义了一个已经被安排的任务将会在什么时候执行的时间条件,比如每2秒就执行一次。
  • JobBuilder-用于声明一个任务实例,也可以定义关于该任务的详情比如任务名、组名等,这个声明的实例将会作为一个实际执行的任务。
  • TriggerBuilder 触发器创建器,用于创建触发器trigger实例。
  • JobListener、TriggerListener、SchedulerListener监听器,用于对组件的监听。

7丶CronExpression表达式

格式:[秒] [分] [时] [每月的第几日] [月] [每周的第几日] [年]

字段名必须的允许值允许的特殊字符
SecondsYES0-59, - * /
MinutesYES0-59, - * /
HoursYES0-23, - * /
Day of monthYES1-31, - * ? / L W
MonthYES1-12 or JAN-DEC, - * /
Day of weekYES1-7 or SUN-SAT, - * ? / L #
YearNOempty, 1970-2099, - * /

 注意:有效范围为1-7的整数或SUN-SAT两个范围。1表示星期天,2表示星期一, 依次类推

特殊字符说明:

字符含义
*用于 指定字段中的所有值。比如:* 在分钟中表示 每一分钟
?用于 指定日期中的某一天,或是 星期中的某一个星期
-用于 指定范围。比如:10-12 在小时中表示 10 点,11 点,12 点
,用于 指定额外的值。比如:MON,WED,FRI 在日期中表示 星期一, 星期三, 星期五
/用于 指定增量。比如:0/15 在秒中表示 0 秒, 15 秒, 30 秒, 45 秒5/15 在秒中表示 5 秒,20 秒,35 秒,50 秒
L在两个字段中拥有不同的含义。比如:L 在日期(Day of month)表示 某月的最后一天。在星期(Day of week)只表示 7SAT。但是,值L 在星期(Day of week)中表示 某月的最后一个星期几。比如:6L 表示 某月的最后一个星期五。也可以在日期(Day of month)中指定一个偏移量(从该月的最后一天开始).比如:L-3 表示 某月的倒数第三天
W用于指定工作日(星期一到星期五)比如:15W 在日期中表示 到 15 号的最近一个工作日。如果第十五号是周六, 那么触发器的触发在 第十四号星期五。如果第十五号是星期日,触发器的触发在 第十六号周一。如果第十五是星期二,那么它就会工作开始在 第十五号周二。然而,如果指定 1W 并且第一号是星期六,那么触发器的触发在第三号周一,因为它不会 "jump" 过一个月的日子的边界。
LW可以在日期(day-of-month)合使用,表示 月份的最后一个工作日
#用于 指定月份中的第几天。比如:6#3 表示 月份的第三个星期五(day 6 = Friday and "#3" = the 3rd one in the month)。其它的有,`2#1 表示 月份第一个星期一4#5 表示 月份第五个星期三。注意: 如果只是指定 #5,则触发器在月份中不会触发。`

注意:字符不区分大小写,MONmon 相同。

cronExpression 示例

表达式含义
0 0 12 * * ?每天中午 12 点
0 15 10 ? * *每天上午 10 点 15 分
0 15 10 * * ?每天上午 10 点 15 分
0 15 10 * * ? *每天上午 10 点 15 分
0 15 10 * * ? 2005在 2005 年里的每天上午 10 点 15 分
0 * 14 * * ?每天下午 2 点到下午 2 点 59 分的每一分钟
0 0/5 14 * * ?每天下午 2 点到 2 点 55 分每隔 5 分钟
0 0/5 14,18 * * ?每天下午 2 点到 2 点 55 分, 下午 6 点到 6 点 55 分, 每隔 5 分钟
0 0-5 14 * * ?每天下午 2 点到 2 点 5 分的每一分钟
0 10,44 14 ? 3 WED3 月每周三的下午 2 点 10 分和下午 2 点 44 分
0 15 10 ? * MON-FRI每周一到周五的上午 10 点 15 分
0 15 10 15 * ?每月 15 号的上午 10 点 15 分
0 15 10 L * ?每月最后一天的上午 10 点 15 分
0 15 10 L-2 * ?每月最后两天的上午10点15分
0 15 10 ? * 6L每月的最后一个星期五的上午 10 点 15 分
0 15 10 ? * 6L 2002-20052002 年到 2005 年每个月的最后一个星期五的上午 10 点 15 分
0 15 10 ? * 6#3每月的第三个星期五的上午 10 点 15 分
0 0 12 1/5 * ?每月的 1 号开始每隔 5 天的中午 12 点
0 11 11 11 11 ?每年 11 月 11 号上午 11 点 11 分

8丶快速开始(入门demo)

        8.1丶新建一个maven项目

导入依赖:

        <!--核心包-->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.2</version>
        </dependency>
        <!--工具-->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz-jobs</artifactId>
            <version>2.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.7</version>
            <scope>compile</scope>
        </dependency>

        8.2丶 编写一个Job类

package com.hzf.quartz.Job;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @ClassName HelloJob
 * @Description TODO
 * @Author Mr.Huang
 * @Date 2022/6/27 10:24
 * @Version 1.0
 **/
public class HelloJob implements Job {
    //其实这里是可以操作数据库的,可以调用service业务的
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        //输出当前时间
        Date date=new Date();
        SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString=dateFormat.format(date);
        //工作内容
        System.out.println("执行定时任务,时间是:"+dateString);
    }
}

        8.3丶编写触发器和调度器

package com.hzf.quartz.test;

import com.hzf.quartz.Job.HelloJob;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

/**
 * @ClassName HelloSchedulerDemo
 * @Description TODO
 * @Author Mr.Huang
 * @Date 2022/6/27 10:28
 * @Version 1.0
 **/
public class HelloSchedulerDemo {
    public static void main(String[] args) throws Exception{
        //1、创建调度器(Schedular),从工厂中获取调度实例(默认:实例化new StdSchedulerFactory();)
        Scheduler scheduler= StdSchedulerFactory.getDefaultScheduler();
        //2、任务实例(JobDetail)
        JobDetail jobDetail= JobBuilder.newJob(HelloJob.class) //加载任务类,与HelloJob完成绑定,要求HelloJob实现Job接口
                .withIdentity("job1","group1") //参数1:任务的名称(唯一实例);参数2:任务组的名称
                .build();
        //3、创建触发器(Trigger)
        Trigger trigger= TriggerBuilder.newTrigger()
                .withIdentity("trigger1","group1") //参数1:触发器的名称(唯一实例);参数2:触发器组的名称
                .startNow() //马上启动触发器
               // .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5)) //每5秒执行一次
                .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))    //使用cronExpression表达式
                .build();
        //4.让调度器关联任务和触发器,保证按照触发器定义的条件执行任务
        scheduler.scheduleJob(jobDetail,trigger);
        //启动
        scheduler.start();
    }
}

        8.4丶运行结果 

9丶SpringBoot 整合 Quartz

        9.1丶引入依赖

        <!--springboot版本-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
        </dependency>

        9.2丶编写配置Quartz类 

                9.2.1丶MyAdaptableJobFactory

package com.hzf.quartz.config;

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component;

/**
 * @ClassName MyAdaptableJobFactory
 * @Description TODO
 * @Author Mr.Huang
 * @Date 2022/6/27 11:27
 * @Version 1.0
 **/
@Component("MyAdaptableJobFactory")  //将该类实例化,使得可以直接用
public class MyAdaptableJobFactory extends AdaptableJobFactory {
    //AutowireCapableBeanFactory可以将一个对象添加到Spring IOC容器中,并且完成该对象注入
    @Autowired
    private AutowireCapableBeanFactory autowireCapableBeanFactory;

    //该方法将实例化的任务对象手动的添加到SpringIOC容器中并且完成对象的注入
    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        Object object = super.createJobInstance(bundle);
        //将object对象添加到Spring IOC容器中并完成注入
        this.autowireCapableBeanFactory.autowireBean(object);
        return object;
    }
}

                9.2.2丶QuartzConfig

package com.hzf.quartz.config;

import com.hzf.quartz.service.QuartzService;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;

/**
 * Quartz(定时任务)配置类
 * @ClassName QuartzConfig
 * @Description TODO
 * @Author Mr.Huang
 * @Date 2022/6/27 10:53
 * @Version 1.0
 **/
@Configuration
public class QuartzConfig {

    /**
     * 1、创建Job对象
     */
    @Bean
    public JobDetailFactoryBean jobDetailFactoryBean(){
        JobDetailFactoryBean factoryBean=new JobDetailFactoryBean();
        //关联我们自己的Job类
        factoryBean.setJobClass(QuartzService.class);
        return factoryBean;
    }

    /**
     * 2、创建Trigger对象
     * 使用setRepeatInterval
     */
    @Bean
    public SimpleTriggerFactoryBean simpleTriggerFactoryBean(@Qualifier("jobDetailFactoryBean") JobDetailFactoryBean jobDetailFactoryBean){
        SimpleTriggerFactoryBean factoryBean=new SimpleTriggerFactoryBean();
        //关联JobDetail对象
        factoryBean.setJobDetail(jobDetailFactoryBean.getObject());
        //该参数表示一个执行的毫秒数
        factoryBean.setRepeatInterval(5000); //每隔5秒执行一次
        //重复次数
        factoryBean.setRepeatCount(5);
        return factoryBean;
    }
    /*
     * 创建Trigger对象
     * 功能描述:
     * 使用cronExpression表达式
     * @Param:
     * @Return:
     * @Author: Mr.Huang
     * @Date: 2022/6/27 15:04
     **/
    @Bean
    public CronTriggerFactoryBean cronTriggerFactoryBean(@Qualifier("jobDetailFactoryBean") JobDetailFactoryBean jobDetailFactoryBean){
        CronTriggerFactoryBean factoryBean=new CronTriggerFactoryBean();
        //关联JobDetail对象
        factoryBean.setJobDetail(jobDetailFactoryBean.getObject());
        factoryBean.setCronExpression("0/5 * * * * ?");   //使用cronExpression表达式
        return factoryBean;
    }

    /**
     * 3、创建Scheduler,一个触发器可以执行多个任务
     * 参数1选择需要的bean类型
     * 参数2把自己注入好的JobFactory加入其中就可以访问数据库了
     */
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean simpleTriggerFactoryBean,MyAdaptableJobFactory myAdaptableJobFactory){
        SchedulerFactoryBean factoryBean=new SchedulerFactoryBean();
        //关联trigger
        factoryBean.setTriggers(simpleTriggerFactoryBean.getObject());
        factoryBean.setJobFactory(myAdaptableJobFactory);
        return factoryBean;
    }
}

        9.3丶 编写QuartzService类

package com.hzf.quartz.service;

import com.hzf.common.entity.User;
import com.hzf.quartz.mapper.UserMapper;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * 定时任务服务
 * @ClassName QuartzService
 * @Description TODO
 * @Author Mr.Huang
 * @Date 2022/6/27 11:25
 * @Version 1.0
 **/
public class QuartzService implements Job {
    @Autowired
    private UserMapper userMapper;

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        List<User> users = userMapper.selectList(null);
        for (User user : users) {
            System.out.println(user.getUserName());
        }
    }
}

        9.4丶 启动器类

package com.hzf.quartz;

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

/**
 * @ClassName QuartzApplication
 * @Description TODO
 * @Author Mr.Huang
 * @Date 2022/6/27 9:42
 * @Version 1.0
 **/
@SpringBootApplication
@EnableScheduling       //开启定时任务
@MapperScan("com.hzf.quartz.mapper")
public class QuartzApplication {
    public static void main(String[] args) {
        SpringApplication.run(QuartzApplication.class,args);
    }
}

        9.5丶applicationyaml配置文件 

spring:
  application:
    name: quartz-service
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://xx.xxx.xxx.xx:3307/onlinebank?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
    username: root
    password: 123456

server:
  port: 8085

mybatis-plus:
  mapper-locations: classpath*:/mapper/*Mapper.xml
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true
  type-aliases-package: com.hzf.common.entity

        9.6丶运行结果

本文参考: Quartz快速入门_Mr.杨先森的博客-CSDN博客_quartz学习

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在SSM项目中使用Quartz进行定时任务可以按照以下步骤进行操作: 1. 配置依赖:在项目的`pom.xml`文件中添加Quartz的依赖。例如: ```xml<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.2</version> </dependency> ``` 2. 创建定时任务类:在您的SSM项目中创建一个定时任务类,可以命名为`JobScheduleTask`。该类需要实现Quartz的`Job`接口,并实现其中的`execute`方法。在`execute`方法中编写定时任务的逻辑代码。 ```javapublic class JobScheduleTask implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { // 定时任务的逻辑代码 // ... } } ``` 3. 配置定时任务触发器:创建一个触发器类,可以命名为`JobScheduleTrigger`。在该类中,使用Quartz的`TriggerBuilder`来配置定时任务触发器的属性,例如执行时间、周期等。 ```javapublic class JobScheduleTrigger { public static Trigger createTrigger() { return TriggerBuilder.newTrigger() .withIdentity("jobScheduleTrigger") .withSchedule(CronScheduleBuilder.cronSchedule("000/1 * * ?")) // 每小时执行一次 .build(); } } ``` 4. 配置定时任务调度器:创建一个调度器类,可以命名为`JobScheduleScheduler`。在该类中,使用Quartz的`SchedulerFactory`来创建调度器实例,并配置相关属性,如数据源、任务存储等。然后使用调度器的`scheduleJob`方法将定时任务和触发器关联起来,并启动调度器。 ```javapublic class JobScheduleScheduler { public static void startScheduler() throws SchedulerException { SchedulerFactory schedulerFactory = new StdSchedulerFactory(); Scheduler scheduler = schedulerFactory.getScheduler(); JobDetail jobDetail = JobBuilder.newJob(JobScheduleTask.class) .withIdentity("jobScheduleTask") .build(); Trigger trigger = JobScheduleTrigger.createTrigger(); scheduler.scheduleJob(jobDetail, trigger); scheduler.start(); } } ``` 5. 在Spring配置文件中配置调度器:在您的Spring配置文件(如`applicationContext.xml`)中,将定时任务调度器配置为一个Bean,并在其中调用`JobScheduleScheduler.startScheduler()`方法。 ```xml<bean id="jobScheduleScheduler" class="com.example.JobScheduleScheduler" init-method="startScheduler" /> ``` 6. 启动项目:启动您的SSM项目,定时任务调度器会根据配置的触发器时间和周期执行定时任务的逻辑。 请注意,以上步骤仅提供了一个基本示例,您可以根据实际需求进行修改和扩展。希望对您有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Abcdzzr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值