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; } }
运行结果是启动的时候就开始循环执行,每一秒执行一次。