Quartz的分享

前言:定时任务的使用,是我们在平时开发项目的过程中经常要用到的,如果你使用的是Spring boot开发那么常用的可能是它本身自带的Scheduled Tasks,它的使用也是非常简单,下面我也介绍了常用的方法。

今天我要分享的主要是关于Quartz在项目中的使用,这一部分在Scheduled Tasks介绍后有所介绍。

Spring Boot提供了一种方便的方式来创建和管理定时任务,这就是Spring框架中的Scheduled Tasks。Scheduled Tasks是一种基于注解的方式,让开发人员可以轻松地创建和管理定时任务。

在Spring Boot中,你可以使用@Scheduled注解来标注一个方法,使其成为一个定时任务。@Scheduled注解可以接收一个cron表达式或者一个固定的时间间隔,以指定任务的执行时间。

下面是一个使用@Scheduled注解创建定时任务的例子:

1
2
3
4
5
6
7
8
@Component
public class MyScheduledTask {

@Scheduled(cron = "0 0 0 * * ?")
public void runTask() {
// 任务执行的逻辑代码
}
}

在上面的例子中,@Scheduled注解标注的runTask()方法是一个每天凌晨执行的定时任务。其中,cron表达式0 0 0 * * ?表示每天的0点0分0秒执行。

除了cron表达式,@Scheduled注解还支持其他的参数,例如:

  • fixedRate:以固定的时间间隔执行任务,无论任务执行的时间是多少。
  • fixedDelay:以固定的时间间隔执行任务,任务执行完成后再等待指定时间间隔后再次执行任务。
  • initialDelay:指定任务第一次执行的延迟时间。

下面是一个使用fixedRate参数创建定时任务的例子:

1
2
3
4
5
6
7
8
@Component
public class MyScheduledTask {

@Scheduled(fixedRate = 5000)
public void runTask() {
// 任务执行的逻辑代码
}
}

在上面的例子中,@Scheduled注解标注的runTask()方法是一个每5秒执行一次的定时任务。其中,fixedRate参数表示任务执行的时间间隔为5秒,无论任务执行的时间是多少。

Spring Boot的Scheduled Tasks可以方便地管理和执行定时任务,使得开发人员可以专注于业务逻辑的实现。同时,Spring Boot还提供了一些有用的工具类和方法,例如TaskScheduler和CronSequenceGenerator等,以更好地支持定时任务的创建和管理。


创建任务

首先,创建某个任务类,使它实现Job接口,重写其**execute()**方法,内部写上自定义业务,即完成了任务的创建。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class MyJob implements Job {
@Autowired
private AddTmEsMsg addTmEsMsg;

private static Logger logger = LoggerFactory.getLogger(MyJob.class);
/**
* 程序启动后执行删除es中的所有文档数据,然后再将新数据添加至文档。
* @param context
* @throws JobExecutionException
*/
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
String indexName = PropertiesUtil.getProperty("elasticsearch.index");
try {
logger.info("开始执行 deleteTransferData 方法...");
addTmEsMsg.deleteTransferData(indexName);
logger.info("deleteTransferData 方法执行完毕");
logger.info("开始执行 addTransferDataToEs 方法...");
addTmEsMsg.addTransferDataToEs(indexName);
logger.info("addTransferDataToEs 方法执行完毕");
} catch (IOException e) {
throw new JobExecutionException("无法执行作业", e);
}
}
}

调用任务

单个任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Component
public class EsRunner implements CommandLineRunner {
private static final Logger logger = LoggerFactory.getLogger(EsRunner.class);

@Autowired
private SchedulerFactoryBean schedulerFactoryBean;

@Override
public void run(String... args) throws Exception {
logger.info("启动调度器...");
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobDetail jobDetail = JobBuilder.newJob(MyJob.class).withIdentity("myJob", "group1").build();
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("myTrigger", "group1")
.startNow()
.build();
scheduler.scheduleJob(jobDetail, trigger);
logger.info("任务已经启动");
}
}

多个任务

如果您需要调度多个任务,您可以考虑使用Quartz的JobDetailTrigger来实现。您可以为每个任务创建一个JobDetail和一个Trigger,然后将它们添加到调度器中以便执行。

以下是一个示例,演示如何调度多个任务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@Autowired
private SchedulerFactoryBean schedulerFactoryBean;

@Override
public void run(String... args) throws Exception {
logger.info("启动调度器...");
Scheduler scheduler = schedulerFactoryBean.getScheduler();

// 创建第一个任务
JobDetail jobDetail1 = JobBuilder.newJob(MyJob1.class).withIdentity("myJob1", "group1").build();
Trigger trigger1 = TriggerBuilder.newTrigger()
.withIdentity("myTrigger1", "group1")
.startNow()
.build();
scheduler.scheduleJob(jobDetail1, trigger1);

// 创建第二个任务
JobDetail jobDetail2 = JobBuilder.newJob(MyJob2.class).withIdentity("myJob2", "group1").build();
Trigger trigger2 = TriggerBuilder.newTrigger()
.withIdentity("myTrigger2", "group1")
.startNow()
.build();
scheduler.scheduleJob(jobDetail2, trigger2);

// 创建第三个任务
JobDetail jobDetail3 = JobBuilder.newJob(MyJob3.class).withIdentity("myJob3", "group1").build();
Trigger trigger3 = TriggerBuilder.newTrigger()
.withIdentity("myTrigger3", "group1")
.startNow()
.build();
scheduler.scheduleJob(jobDetail3, trigger3);

logger.info("所有任务已经启动");
}

在这个示例中,我们创建了三个任务,并将它们添加到调度器中以便执行。每个任务都有一个独立的JobDetailTrigger,并且它们都属于同一个组。您可以根据需要创建更多的任务,并将它们添加到调度器中。

请注意,这个示例中的MyJob1MyJob2MyJob3是自定义的任务类,您需要根据自己的需求来实现它们。这些任务类应该实现Job接口,并且需要在execute方法中实现任务的具体逻辑。

重写run()方法,加入自定义的任务并在类上加入@component交由Spring容器管理的对象管理,即可在程序启动的时候执行我们的任务。