Spring自带的定时任务只能在项目初始化时创建定时任务,通过ScheduledAnnotationBeanPostProcessor类处理@Scheduled注解并注册定时任务,无法灵活手动创建定时任务,接下来附上Quartz创建定时任务的用法。
- 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
- 编写测试类
package com.xxx.xxx;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.quartz.*;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTest {
@Resource
private SchedulerFactoryBean schedulerFactoryBean;
@Test
public void test(){
try {
TimeUnit.SECONDS.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
Scheduler scheduler = schedulerFactoryBean.getScheduler();
try {
scheduler.scheduleJob(JobBuilder.newJob(((Job) jobExecutionContext -> System.out.println(LocalDateTime.now())).getClass())
.withIdentity("job1")
.build(),
TriggerBuilder.newTrigger().withIdentity("trigger1")
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(2).repeatForever()).build());
} catch (SchedulerException e) {
e.printStackTrace();
}
try {
TimeUnit.MINUTES.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
其中,schedulerFactoryBean持有Scheduler,scheduler.scheduleJob()方法需要传入需要执行的任务以及定时任务触发器,任务实现
org.quartz.Job接口。
- 注意事项
当任务的id相同即withIdentity()传入的参数重复时,会出现异常:org.quartz.ObjectAlreadyExistsException: Unable to store Job : 'DEFAULT.job1', because one already exists with this identification.
以上是Quartz最简单的使用方式,更多内容待深究。