首先准备工作:
pom.xml引入相应的依赖,springboot2.0已经将Quartz集成进来,通过引入spring-boot-starter-quartz就可以
springboot的版本采用2.0.0.M6org.springframework.boot spring-boot-starter-parent 2.0.0.M6
由于很多maven仓库没有引入此依赖。需要添加如下配置:
spring-milestones Spring Milestones https://repo.spring.io/libs-milestone false
springboot本身提供比较简单的定时任务代码如下:
@SpringBootApplication @EnableScheduling public class TestApplication { public static void main(String[] args) { SpringApplication.run(TestApplication.class, args); } }
@Component
public class SchedulerTask {
private int count=0;
@Scheduled(cron="*/6 * * * * ?")
private void process(){
System.out.println("this is scheduler task runing "+(count++));
}
}
@Component
public class Scheduler2Task {
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
@Scheduled(fixedRate = 6000)
public void reportCurrentTime() {
System.out.println("现在时间:" + dateFormat.format(new Date()));
}
}
@Scheduled(fixedRate = 6000)表示固定没6s执行一次
@Scheduled(fixedDelay = 6000)表示从上一次任务执行结束延迟6s执行
@Scheduled(initialDelay=1000, fixedRate=6000)
表示第一次执行延迟1s.以后每6s执行一次
cron 一共有 7 位,最后一位是年,Spring Boot 定时方案中只需要设置 6 位即可:
- 第一位,表示秒,取值 0-59;
- 第二位,表示分,取值 0-59;
- 第三位,表示小时,取值 0-23;
- 第四位,日期天/日,取值 1-31;
- 第五位,日期月份,取值 1-12;
- 第六位,星期,取值 1-7,星期一、星期二…;
注:不是第1周、第2周的意思,另外:1表示星期天,2表示星期一。
- 第七位,年份,可以留空,取值 1970-2099。
cron 中,还有一些特殊的符号,含义如下:
(*)星号:可以理解为每的意思,每秒、每分、每天、每月、每年……。
(?)问号:问号只能出现在日期和星期这两个位置,表示这个位置的值不确定,每天 3 点执行,所以第六位星期的位置是不需要关注的,就是不确定的值。同时,日期和星期是两个相互排斥的元素,通过问号来表明不指定值。假如 1 月 10 日是星期一,如果在星期的位置是另指定星期二,就前后冲突矛盾了。
(-)减号:表达一个范围,如在小时字段中使用“10-12”,则表示从 10~12 点,即 10、11、12。
(,)逗号:表达一个列表值,如在星期字段中使用“1、2、4”,则表示星期一、星期二、星期四。
(/)斜杠:如 x/y,x 是开始值,y 是步长,比如在第一位(秒) 0/15 就是,从 0 秒开始,每 15 秒,最后就是 0、15、30、45、60,另 */y,等同于 0/y。
下面列举几个常用的例子。
0 0 3 * * ? 每天 3 点执行。
0 5 3 * * ? 每天 3 点 5 分执行。
0 5 3 ? * * 每天 3 点 5 分执行,与上面作用相同。
0 5/10 3 * * ? 每天 3 点的 5 分、15 分、25 分、35 分、45 分、55 分这几个时间点执行。
0 10 3 ? * 1 每周星期天,3点10分 执行,注:1 表示星期天。
0 10 3 ? * 1#3 每个月的第 三 个星期,星期天执行,# 号只能出现在星期的位置。
定义一个定时任务继承QuartzJobBean.重写executeInternal方法
/** * 定时任务: 描述信息 * 创建任务接口实现QuartzJobBean * @author liyy * @date 2018-07-17 20:33 */ public class SampleJob extends QuartzJobBean { private String name; public void setName(String name){ this.name = name; } @Override protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { System.out.println(String.format("Hello %s!", this.name)); } }
创建调度器,概念一:jobDetail 概念二:Trigger
/** * 定义任务明细、触发器、调度: 描述信息 * * @author liyy * @date 2018-07-17 20:38 */ @Configuration public class SampleScheduler { /** * 定义任务明细,实例化一个新的job实例 * @return */ @Bean public JobDetail sampleJobDetail(){ return JobBuilder.newJob(SampleJob.class).withIdentity("sampleJob") .usingJobData("name", "World").storeDurably().build(); } /** * 定义触发器,没两秒执行一次 * @return */ @Bean public Trigger sampleJobTrigger() { SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(2).repeatForever(); return TriggerBuilder.newTrigger().forJob(sampleJobDetail()) .withIdentity("sampleTrigger").withSchedule(scheduleBuilder).build(); }
上述是比较简单的定时任务,如下是自己写的两个定时任务:
package com.neo.cronjob; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; /** * 定时任务一: 描述信息 * * @author liyy * @date 2018-07-17 20:50 */ public class ScheduledJob implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { System.out.println("我是定时任务1,schedule job1 is running ..."); } }
package com.neo.cronjob; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; /** * 定时任务二: 描述信息 * * @author liyy * @date 2018-07-17 20:50 */ public class ScheduledJob2 implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { System.out.println("我是定时任务2,schedule job2 is running ..."); } }
package com.neo.cronjob; import com.neo.job.SampleJob; import org.quartz.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.quartz.SchedulerFactoryBean; /** * 调度中心: 描述信息 * * @author liyy * @date 2018-07-18 10:08 */ @Configuration public class SchedulerCenter { @Autowired private SpringJobFactory springJobFactory; /** * 调度定时任务一每6秒执行一次 * @param scheduler * @throws SchedulerException */ public void scheduleJob1(Scheduler scheduler) throws SchedulerException{ //创建任务明细,名称job1,组group1 JobDetail jobDetail = JobBuilder.newJob(ScheduledJob.class) .withIdentity("job1", "group1").build(); //每6s执行一次,创建调度 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/6 * * * * ?"); //创建触发器,名称trigger1,组group1 CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1") .withSchedule(scheduleBuilder).build(); scheduler.scheduleJob(jobDetail,cronTrigger); } /** * 调度任务2每12秒执行一次 * @param scheduler * @throws SchedulerException */ public void scheduleJob2(Scheduler scheduler) throws SchedulerException{ //创建任务明细,名称job1,组group1 JobDetail jobDetail = JobBuilder.newJob(ScheduledJob2.class) .withIdentity("job2", "group2").build(); //每6s执行一次,创建调度 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/12 * * * * ?"); //创建触发器,名称trigger1,组group1 CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger2", "group2") .withSchedule(scheduleBuilder).build(); scheduler.scheduleJob(jobDetail,cronTrigger); } @Bean(name = "schedulerFactoryBean") public SchedulerFactoryBean schedulerFactoryBean() { SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); schedulerFactoryBean.setJobFactory(springJobFactory); return schedulerFactoryBean; } }
package com.neo.cronjob; 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; /** * : 描述信息 * * @author liyy * @date 2018-07-18 10:35 */ @Component public class SpringJobFactory extends AdaptableJobFactory { @Autowired private AutowireCapableBeanFactory capableBeanFactory; @Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { Object jobInstance = super.createJobInstance(bundle); capableBeanFactory.autowireBean(jobInstance); return jobInstance; } }
package com.neo.cronjob; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.quartz.SchedulerFactoryBean; import org.springframework.stereotype.Component; /** * 调度者: 描述信息 * * @author liyy * @date 2018-07-18 10:36 */ @Component public class ScheduleUser { @Autowired private SchedulerFactoryBean schedulerFactoryBean; @Autowired private SchedulerCenter schedulerCenter; public void scheduleJobs() throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); schedulerCenter.scheduleJob1(scheduler); schedulerCenter.scheduleJob2(scheduler); } }
package com.neo.cronjob; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; /** * 启动定时任务类: 描述信息 * * @author liyy * @date 2018-07-18 10:43 */ @Component public class MyStartupRunner implements CommandLineRunner{ @Autowired private ScheduleUser scheduleUser; @Override public void run(String... args) throws Exception { scheduleUser.scheduleJobs(); System.out.println(">>>>>>>>>>>>>>>定时任务开始执行<<<<<<<<<<<<<"); } }
以上代码,亲自测试过。run起来没问题