1. 通过 @Scheduled 注解配置定时任务

在 SpringBoot项目中使用 @Scheduled 注解只需要添加 Spring Web 依赖,并且在项目启动类中开启 @EnableScheduling 注解即可。

创建项目

关闭spring定时任务 spring开启定时任务_关闭spring定时任务

在项目启动类中添加 @EnableScheduling 注解。

@SpringBootApplication
@EnableScheduling // 开启 @Scheduled 
public class ScheduledApplication {
    public static void main(String[] args) {
        SpringApplication.run(ScheduledApplication.class, args);
    }

}

使用 @Scheduled 注解,实现定时任务。项目在启动时,定时任务默认情况下会第一时间启动,可以在 @Scheduled 注解中添加属性进行设置,时间单位为毫秒。

@Component
public class MySchedule {

    // fixedDelay=1000 表示定时任务完成,之后每 1 秒,启动一次定时任务。
    @Scheduled(fixedDelay = 1000)
    public void fixedDelay(){
        System.out.println("fixedDelay : " + new Date());
    }
    // fixedRate = 1000 表示定时任务启动,之后每一秒,启动一次定时任务
    @Scheduled(fixedRate = 1000)
    public void fixedRate(){
        System.out.println("fixedRate : " + new Date());
    }

    // initialDelay = 1000 表示项目启动之后 1 秒再启动定时任务。
    @Scheduled(initialDelay = 1000,fixedRate = 1000)
    public void initDelay(){
        System.out.println("initDelay : " + new Date());
    }
}

同时 @Scheduled 支持 cron 表达式。

cron 表达式格式:【秒】【分】【小时】【日】【月】【周】【年】

序号

说明

是否必填

允许填写的值

允许的通配符

1



0-59

– * /

2



0-59

– * /

3



0-23

– * /

4



1-31

– * ? / L W

5



1-12 or JAN-DEC

– * /

6



1-7 or SUN-SAT

– * ? / L ##

7



1970-2099

– * /

通配符含义:

  • ? 表示不指定值,即不关心某个字段的取值时使用。需要注意的是,月份中的日期和星期可能会起冲突,因此在配置时这两个得有一个是 ?
  • * 表示所有值,例如:在秒的字段上设置 *,表示每一秒都会触发
  • , 用来分开多个值,例如在周字段上设置 “MON,WED,FRI” 表示周一,周三和周五触发
  • - 表示区间,例如在秒上设置 “10-12”,表示 10,11,12秒都会触发
  • / 用于递增触发,如在秒上面设置”5/15″ 表示从5秒开始,每增15秒触发(5,20,35,50)
  • ## 序号(表示每月的第几个周几),例如在周字段上设置”6##3″表示在每月的第三个周六,(用 在母亲节和父亲节再合适不过了)
  • 周字段的设置,若使用英文字母是不区分大小写的 ,即 MON 与mon相同
  • L 表示最后的意思。在日字段设置上,表示当月的最后一天(依据当前月份,如果是二月还会自动判断是否是润年), 在周字段上表示星期六,相当于”7″或”SAT”(注意周日算是第一天)。如果在”L”前加上数字,则表示该数据的最后一个。例如在周字段上设置”6L”这样的格式,则表示”本月最后一个星期五”
  • W 表示离指定日期的最近工作日(周一至周五),例如在日字段上设置”15W”,表示离每月15号最近的那个工作日触发。如果15号正好是周六,则找最近的周五(14号)触发, 如果15号是周未,则找最近的下周一(16号)触发,如果15号正好在工作日(周一至周五),则就在该天触发。如果指定格式为 “1W”,它则表示每月1号往后最近的工作日触发。如果1号正是周六,则将在3号下周一触发。(注,”W”前只能设置具体的数字,不允许区间”-“)
  • LW 可以一组合使用。如果在日字段上设置”LW”,则表示在本月的最后一个工作日触发(一般指发工资 )

例如,在 @Scheduled 注解中来一个简单的 cron 表达式,每隔5秒触发一次,如下:

@Scheduled(cron = "0/5 * * * * *")
public void cron() {
    System.out.println(new Date());
}

2. 通过 Quartz 注解配置定时任务

使用 Quartz Scheduler 需要添加以下依赖。

关闭spring定时任务 spring开启定时任务_关闭spring定时任务_02

在 SpringBoot 中使用 Quartz 实现定时任务,我们需要提供三个部分

  • 定时任务将要执行的方法(job)
  • 触发器,什么时候触发定时任务(trigger)
  • 启动器,将触发器添加到启动器中

定义定时任务有两种方式:

  1. 通过 注入普通的 java bean 方式,这种方式在设置定时任务时,需要指定目标方法。毕竟系统不知道将来要执行哪一个方法

创建一个普通 java bean :

@Component
public class MyJob01 {

    public void sayHello(){
        System.out.println("MyJob01 : " + new Date());
    }
}

在配置类中设置为定时任务:

@Bean
MethodInvokingJobDetailFactoryBean jobDetail01(){
    MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
    // 指定 job
    bean.setTargetBeanName("myJob01");
    // 指定 job 执行的目标方法
    bean.setTargetMethod("sayHello");
    return bean;
}
  1. 通过继承 QuartzJobBean 类的方式,这种方式在设置定时任务时,不需要指定目标方法。原因是继承 QuartzJobBean 类时重写的 executeInternal 方法就是将来定时任务执行的方法。并且,这种方式允许传入参数。

继承 QuartzJobBean 类

public class MyJob02 extends QuartzJobBean {

    private String name;

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

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

在配置类中设置为定时任务:

@Bean
JobDetailFactoryBean jobDetail02(){
    JobDetailFactoryBean bean = new JobDetailFactoryBean();
    // 指定的执行方法类
    bean.setJobClass(MyJob02.class);
    // 通过 JobDataMap 传入参数
    JobDataMap map = new JobDataMap();
    map.put("name","crc");
    bean.setJobDataMap(map);
    return bean;
}

定义触发器为每个注入好的定时任务设置一个触发器,设置定时任务触发的时机、间隔、延迟等参数信息。

这里主要介绍两种触发器类型:

  1. 简单类型的触发器。

在配置类中进行配置:

// 简单类型的触发器
@Bean
SimpleTriggerFactoryBean simpleTriggerFactoryBean(){
    SimpleTriggerFactoryBean bean = new SimpleTriggerFactoryBean();
    // 触发器触发的 bean
    bean.setJobDetail(jobDetail01().getObject());
    // 重复此时
    bean.setRepeatCount(3);
    // 启动延迟
    bean.setStartDelay(1000);
    // 重复间隔时间
    bean.setRepeatInterval(1000);
    return bean;
}
  1. 使用 cron 表达式的触发器
// 使用 cron 表达式的触发器
@Bean
CronTriggerFactoryBean cronTriggerFactoryBean(){
    CronTriggerFactoryBean bean = new CronTriggerFactoryBean();
    bean.setJobDetail(jobDetail02().getObject());
    bean.setCronExpression("0/5 * * * * ?");
    return bean;
}

定义启动器,将设置好的触发器添加到启动器中。

// 启动器,将设置好的触发器,加入启动器中
@Bean
SchedulerFactoryBean schedulerFactoryBean(){
    SchedulerFactoryBean bean = new SchedulerFactoryBean();
    // 将上面注入容器中的触发器加入启动器中
    bean.setTriggers(simpleTriggerFactoryBean().getObject(),cronTriggerFactoryBean().getObject());
    return bean;
}

至此,通过 Quartz 实现定时任务。