SpringBoot定时任务

1.使用自带的Schedule

SpringBoot中自带有定时任务,用法很简单。

第一步:在启动类上面开启定时任务的注解

@SpringBootApplication
@EnableScheduling//开启定时任务
public class Demo2Application {

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

}

第二步:配置定时任务。

1)fixedDelay

表示这个方法上一次执行完成后再过多少秒后再次执行,或者这次执行完毕后,距离下次执行需要多少秒。

创建两个定时任务,如下

package com.example.demo;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

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

@Component
public class MyScheduleTask1 {
    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    // fixedDelay:上一次执行完毕之后再过6秒再执行,或者这次执行完毕后,距离下次执行需要6s
    @Scheduled(fixedDelay = 6000)
    public void fixedDelay(){
        System.out.println("我是定时任务1,我6s后被再次执行,现在时间"+sdf.format(new Date()));
    }
    // fixedDelay:这次执行完毕后,距离下次执行需要10s
    @Scheduled(fixedDelay = 10000)
    public void fixedDelay2(){
        System.out.println("我是定时任务2,我10s后被再次执行,现在时间"+sdf.format(new Date()));
    }
}

运行结果如下

结果分析:创建了两个定时任务,首先fixedDelay的任务在首次启动时都会先执行一次,然后定时任务1执行完成后再过6秒再次执行,定时任务2执行完成后再过10秒再次执行,就这样一直循环执行。

2)fixedRate

上一次开始执行后每隔多少秒执行一次,可能再次执行时这个方法的上一次执行还没有完毕,代码如下

    // fixedDelay:上一次执行完毕之后再过6秒再执行,或者这次执行完毕后,距离下次执行需要6s
    @Scheduled(fixedDelay = 6000)
    public void fixedDelay(){
        System.out.println("我是定时任务1,我6s后被再次执行,现在时间"+sdf.format(new Date()));
    }
   // fixedRate:上一次开始执行后每隔8秒执行一次,可能再次执行时这个方法的上一次执行还没有完毕。
    @Scheduled(fixedRate = 8000)
    public void fixedRate(){
        System.out.println("我是定时任务2,我8s后被再次执行,现在时间"+sdf.format(new Date()));
    }

运行结果如下

 结果分析:创建了两个定时任务,首先fixedDelay和fixedRate的任务在首次启动时都会先执行一次,然后定时任务1执行完成后再过6秒再次执行,定时任务2首次执行后每隔8秒再次执行,此时这个方法可能还没有执行完毕,就这样一直循环执行。

3)initialDelay

在首次启动后延迟多少秒去执行,后面根据fixedDelay区执行,代码如下

   // fixedDelay:上一次执行完毕之后再过6秒再执行,或者这次执行完毕后,距离下次执行需要6s
    @Scheduled(fixedDelay = 6000)
    public void fixedDelay(){
        System.out.println("我是定时任务1,我6s后被再次执行,现在时间"+sdf.format(new Date()));
    }
    // initialDelay:在首次启动后延迟5s去执行,后面根据fixedDelay区执行
    int i=1;
    @Scheduled(initialDelay = 5000,fixedDelay = 10000)
    public void initialDelay(){
        if(i==1){
            System.out.println("我是定时任务2,我首次启动延迟5秒执行,现在时间"+sdf.format(new Date()));
            i++;
        }else{
            System.out.println("我是定时任务2,我不是首次启动,我执行完成后再过10秒执行,现在时间"+sdf.format(new Date()));
        }
    }

运行结果如下

  结果分析:创建了两个定时任务,首先fixedDelay的任务在首次启动时会先执行一次,然后定时任务1执行完成后再过6秒再次执行,定时任务2首次启动延迟5秒执行,然后执行完成后过10秒再次执行,就这样一直循环执行。

4)cron

隔某一段时间或在某个时间段触发,这个可以设置较长的时间,如一天触发一次、每个月15号触发等。

完整字段:秒 分 小时 日 月 周 年。注意中间用空格隔开。

常用示例:

cron 说明
0 * * * * * ? 每分钟触发
 0 */5 * * * ? 每5分钟触发
0 0 */2 * * ? 每两个小时触发
0 0 2 * * ? 每天凌晨2点触发 
0 5 2/3 * * ? 每天凌晨2:05开始,每3小时触发一次
0 15 10 * * ? 每天上午10:15触发
0 0 0 1 * ? 每月1号0点触发
0 0 10,14,16 * * ? 每天上午10点,下午2点,下午4点各触发一次

 

下面的定时任务是每一分钟触发一次

//cron:在某一段时间后触发,这个可以设置较长的时间,如一天、一年等
    @Scheduled(cron = "0 * * * * ?")
    public void cron(){
        System.out.println("我是定时任务,我每一分钟都触发,现在时间"+sdf.format(new Date()));
    }

运行结果如下

2.使用Quartz

动态执行quartz的代码地址:https://github.com/zhongyushi-git/quartz-mange.git

Quartz可以创建简单或复杂的执行计划,支持数据库、集群、邮件等。

2.1导入依赖

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

2.2第一种方式(无参数)

1)创建定时任务类

package com.zys.mybatisplusdemo.config;

import org.springframework.stereotype.Component;

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

@Component
public class MyJob {
    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    public void sayHello(){
        System.out.println("MyJob:sayHello now "+sdf.format(new Date()));
    }
}

2)配置定时任务

package com.zys.mybatisplusdemo.config;

import org.quartz.SimpleTrigger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;

@Configuration
public class QuartzConfig {
    @Bean
    public MethodInvokingJobDetailFactoryBean jobDetail(){
        MethodInvokingJobDetailFactoryBean bean=new MethodInvokingJobDetailFactoryBean();
        bean.setTargetBeanName("myJob");//指定job的实例名
        bean.setTargetMethod("sayHello");//指定要调用的方法
        return bean;
    }

    @Bean
    public SimpleTriggerFactoryBean simpleTrigger(){
        SimpleTriggerFactoryBean bean = new SimpleTriggerFactoryBean();
        bean.setJobDetail(jobDetail().getObject());
        bean.setRepeatCount(5);//任务循环次数
        bean.setStartDelay(6000);//任务启动延迟时间
        bean.setRepeatInterval(3000);//任务时间间隔
        return bean;
    }

    @Bean
    public SchedulerFactoryBean schedulerFactory(){
        SchedulerFactoryBean bean=new SchedulerFactoryBean();
        SimpleTrigger simpleTrigger = simpleTrigger().getObject();
        bean.setTriggers(simpleTrigger);
        return bean;
    }
}

运行结果是在启动后延迟6秒执行,然后每隔3秒再重复执行5次就不执行了。

2.3第二种方式(有参数)

1)创建定时任务类

package com.zys.mybatisplusdemo.config;

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

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

@Component
public class MyJob  extends QuartzJobBean {
    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private String name;

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

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("hello:"+name+",现在的时间是"+sdf.format(new Date()));
    }
}

2)配置定时任务

package com.zys.mybatisplusdemo.config;

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

@Configuration
public class QuartzConfig {
    @Bean
    public JobDetailFactoryBean jobDetail2(){
        JobDetailFactoryBean bean = new JobDetailFactoryBean();
        bean.setJobClass(MyJob.class);
        JobDataMap map=new JobDataMap();
        map.put("name","嘻嘻嘻");//传递参数
        bean.setJobDataMap(map);
        return  bean;
    }
    @Bean
    public CronTriggerFactoryBean cronTrigger(){
        CronTriggerFactoryBean bean=new CronTriggerFactoryBean();
        bean.setJobDetail(jobDetail2().getObject());
        bean.setCronExpression("* * * * * ?");//配置cron的表达式
        return bean;
    }

    @Bean
    public SchedulerFactoryBean schedulerFactory(){
        SchedulerFactoryBean bean=new SchedulerFactoryBean();
        CronTrigger cronTrigger= cronTrigger().getObject();
        bean.setTriggers(cronTrigger);
        return bean;
    }
}

运行结果是启动的时候就开始循环执行,每一秒执行一次。

posted @ 2021-07-12 10:12  钟小嘿  阅读(534)  评论(0编辑  收藏  举报