SpringBoot 使用 Spring Task 和 Quartz 两种方式实现定时任务

Java web 应用中常用的两种定时任务解决方案案例

一、 Java 定时任务的其他解决方案

首先对定时任务实现方式做一个总结:

  1. TimerTask ,等于一个线程隔一段时间运行一下。

  2. ScheduledExecutorService ,线程池版的 TimerTask。

  3. Spring 支持的定时任务,@SchSedule注解 ,支持 cron 表达式。

  4. Quartz ,比较流行的任务调度工具,在 SpringMVC 配置起来麻烦,但是在 SpringBoot 中就变得很容易使用。

1、2 两种方案时 Java 最基础的定时任务方案,原理就是线程的执行,TimerTask 为单线程,多个任务无法同时执行。 ScheduledExecutorService 为 TimerTask 补充了线程池,但是在现在来说都很少再去使用这些,3、4 方案最为实用,其中 Spring Task 可以视为轻量级的 Quartz ,简单易用;Quartz 功能全面,simpleSchedule 和 cronSchedule 两种时间表配置方案满足简单和复杂的任务调度方案。

二、 Spring Task

实现方式很简单,SpringBoot 主入添加 @EnableScheduling 注解,具体任务方法使用 @Scheduled 注解

具体代码实现:

主入口:

@EnableScheduling
@SpringBootApplication
public class DemoApplication {

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

具体任务类:

@Component
public class SpringTask {
    @Scheduled(cron = "*/5 * * * * *")//五秒运行一次
    public void taskRun(){
        System.out.println("Spring task run ——" + new Date());
    }
}

cron 的作用就是设定定时任务的执行时间,与 Quartz 的 cronSchedule 使用几乎一样,我们等会一并介绍。

然后运行就可以了

三、 Quartz

在 SpringBoot 2.0 以后集成 Quartz 变得非常简单,Quartz 有了自己的 starter 依赖。

首先加入依赖包:

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-quartzartifactId>
        dependency>

编写具体任务类,需要继承 QuartzJobBean 类:

public class QuartzTask extends QuartzJobBean {
    /**
     * 定时任务方法
     * @param jobExecutionContext
     * @throws JobExecutionException
     */
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("Quartz Task run --:" + new Date());
    }
}

写好继承后,IDEA 中直接用快捷键 ctrl+i 插入重写方法。

然后编写配置类 QuartzConfig ,SpringBoot 中推荐使用 Bean 的方式配置。

@Configuration
public class QuartzConfig {

    @Bean
    public JobDetail teatQuartzDetail(){
        return JobBuilder.newJob(QuartzTask.class).withIdentity("quartzQuartz").storeDurably().build();
    }
    @Bean
    public Trigger testQuartzTrigger(){
        // 简单的时间表配置
        SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(10)  //设置时间周期单位秒
                .repeatForever();
        // 需求复杂时使用这种方式
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("*/10 * * * * ?");// 十秒运行一次
        return TriggerBuilder.newTrigger().forJob(teatQuartzDetail())
                .withIdentity("quartzQuartz")
                .withSchedule(cronScheduleBuilder)
                .build();
    }
    //多任务的话就声明多个 trigger
}

然后启动项目

SpringBoot 使用 Spring Task 和 Quartz 两种方式实现定时任务_第1张图片

Quartz cron 表达式

cron 的表达式是字符串,实际上是由七子表达式,描述个别细节的时间表。
分别代表:

  1. Seconds
  2. Minutes
  3. Hours
  4. Day-of-Month
  5. Month
  6. Day-of-Week
  7. Year (可选字段)

有效值表:
Seconds (秒) :可以用数字0-59 表示,
Minutes(分) :可以用数字0-59 表示,
Hours(时) :可以用数字0-23表示,
Day-of-Month(天)   :可以用数字1-31 中的任一一个值,但要注意一些特别的月份
Month(月) :可以用0-11 或用字符串 “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC” 表示
Day-of-Week(每周)   :可以用数字1-7表示(1 = 星期日)或用字符口串“SUN, MON, TUE, WED, THU, FRI and SAT”表示
 “*”:指定所有的值,比如,Minutes 设置为 *,表示每分钟
“/”:为特别单位,表示为“每”如“0/15”表示每隔15分钟执行一次,“0”表示为从“0”分开始, “3/20”表示表示每隔20分钟执行一次,“3”表示从第3分钟开始执行
 “?”:表示每月的某一天,或第周的某一天
 “L”:用于每月,或每周,表示为每月的最后一天,或每个月的最后星期几如“6L”表示“每月的最后一个星期五”
 “W”:表示为最近工作日,如“15W”放在每月(day-of-month)字段上表示为“到本月15日最近的工作日”
 “#”:是用来指定“的”每月第n个工作日,例 在每周(day-of-week)这个字段中内容为"6#3" or “FRI#3” 则表示“每月第三个星期五”

表达式示例:

每隔5秒执行一次:*/5 * * * * ?
每隔1分钟执行一次:0 */1 * * * ?
每天23点执行一次:0 0 23 * * ?
每天凌晨1点执行一次:0 0 1 * * ?
每月1号凌晨1点执行一次:0 0 1 1 * ?
每月最后一天23点执行一次:0 0 23 L * ?
每周星期天凌晨1点实行一次:0 0 1 ? * L
在26分、29分、33分执行一次:0 26,29,33 * * * ?
每天的0点、13点、18点、21点都执行一次:0 0 0,13,18,21 * * ?
每天的7点到21点都执行一次:0 0 7-21 * * ?

  • 一个专业生成 cron 的网站:cron 生成器

Spring Task 与 Quartz 对比

  1. Quartz 提供了完整的分布式并发支持,Spring task 的话还是需要自己手动配置线程池以及借助其他分布式工具实现。
  2. Quartz 支持调度信息持久化,可以去 Quartz 官方网站下载建表 sql,然后配置数据源等信息实现持久化, Spring task 不支持持久化。
  3. Spring Task 使用起来非常简单,Quartz 还需要写其他配置相对来说比 Spring Task 复杂点。

需求简单的话可以直接使用 Spring Task ,比如一个简单的数据对接接口。如果会有复杂的业务需求不如一步到位,直接使用 Quartz。

你可能感兴趣的:(日常笔记,quartz,java,cron,spring)