简单的定时任务可以直接通过 Spring 中的 @Scheduled 注解来实现,复杂的定时任务则可以通过集成 Quartz 来实现,下面分别介绍。
创建 Spring Boot Web 项目,添加 Web 依赖即可,如下
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
在项目启动类上添加 @EnableScheduling 注解开启定时任务
@SpringBootApplication
@EnableScheduling
public class ScheduledApplication {
public static void main(String[] args) {
SpringApplication.run(ScheduledApplication.class, args);
}
}
定时任务主要通过 @Scheduled 注解进行配置,如下
@Component
public class MySchedule {
@Scheduled(fixedDelay = 1000)
public void fixedDelay() {
System.out.println("fixedDelay:"+new Date());
}
@Scheduled(fixedRate = 2000)
public void fixedRate() {
System.out.println("fixedRate:"+new Date());
}
@Scheduled(initialDelay = 1000,fixedRate = 2000)
public void initialDelay() {
System.out.println("initialDelay:"+new Date());
}
@Scheduled(cron = "0 * * * * ?")
public void cron() {
System.out.println("cron:"+new Date());
}
}
代码解释:
配置完成,接下来启动 Spring Boot 项目即可,部分打印日志如下
initialDelay:Tue Aug 16 17:35:59 CST 2022
fixedDelay:Tue Aug 16 17:35:59 CST 2022
cron:Tue Aug 16 17:36:00 CST 2022
fixedRate:Tue Aug 16 17:36:00 CST 2022
fixedDelay:Tue Aug 16 17:36:00 CST 2022
initialDelay:Tue Aug 16 17:36:01 CST 2022
fixedDelay:Tue Aug 16 17:36:01 CST 2022
fixedRate:Tue Aug 16 17:36:02 CST 2022
fixedDelay:Tue Aug 16 17:36:02 CST 2022
initialDelay:Tue Aug 16 17:36:03 CST 2022
fixedDelay:Tue Aug 16 17:36:03 CST 2022
fixedRate:Tue Aug 16 17:36:04 CST 2022
fixedDelay:Tue Aug 16 17:36:04 CST 2022
initialDelay:Tue Aug 16 17:36:05 CST 2022
fixedDelay:Tue Aug 16 17:36:05 CST 2022
fixedRate:Tue Aug 16 17:36:06 CST 2022
Quartz 是一个功能丰富的开源作业调度库,它由 Java 写成,可以集成在任何 Java 应用程序总,包括 Java SE 和 Java EE 等。
使用 Quartz 可以创建简单或者复杂的执行计划,它支出数据库、集群、插件以及邮件,并且支持 cron 表达式,具有极高的灵活性。
Spring Boot 中集成 Quartz 和 Spring 中集成 Quartz 比较类似,主要提供三个 Bean :JobDetail、Trigger 以及 SchedulerFactory。
首先创建 Spring Boot 项目,添加 Quartz 依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-quartzartifactId>
dependency>
然后创建两个 Job
@Component
public class MyFirstJob {
public void sayHello() {
System.out.println("MyFirstJob:sayHello:"+new Date());
}
}
public class MySecondJob extends QuartzJobBean {
private String name;
public void setName(String name) {
this.name = name;
}
@Override
protected void executeInternal(JobExecutionContext context){
System.out.println("hello:"+name+":"+new Date());
}
}
Job 可以是一个普通的 JavaBean ,如果是普通的 Java Bean ,那么可以先添加 @Component 注解将其注册到 Spring 容器中。
Job 也可以继承抽象类 QuartzJobBean ,若继承 QuartzJobBean ,则需要实现该类中的 executeInternal 方法,该方法在任务被调用时使用。
接下来创建 QuartzConfig 对 JobDetail 和 Tigger 进行配置,如下
@Configuration
public class QuartzConfig {
@Bean
MethodInvokingJobDetailFactoryBean jobDetail1() {
MethodInvokingJobDetailFactoryBean bean =
new MethodInvokingJobDetailFactoryBean();
bean.setTargetBeanName("myFirstJob");
bean.setTargetMethod("sayHello");
return bean;
}
@Bean
JobDetailFactoryBean jobDetail2() {
JobDetailFactoryBean bean = new JobDetailFactoryBean();
bean.setJobClass(MySecondJob.class);
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("name","sang");
bean.setJobDataMap(jobDataMap);
bean.setDurability(true);
return bean;
}
@Bean
SimpleTriggerFactoryBean simpleTrigger() {
SimpleTriggerFactoryBean bean =
new SimpleTriggerFactoryBean();
bean.setJobDetail(jobDetail1().getObject());
bean.setRepeatCount(3);
bean.setStartDelay(1000);
bean.setRepeatInterval(2000);
return bean;
}
@Bean
CronTriggerFactoryBean cronTrigger() {
CronTriggerFactoryBean bean =
new CronTriggerFactoryBean();
bean.setJobDetail(jobDetail2().getObject());
bean.setCronExpression("* * * * * ?");
return bean;
}
@Bean
SchedulerFactoryBean schedulerFactory() {
SchedulerFactoryBean bean = new SchedulerFactoryBean();
SimpleTrigger simpleTrigger = simpleTrigger().getObject();
CronTrigger cronTrigger = cronTrigger().getObject();
bean.setTriggers(simpleTrigger,cronTrigger);
return bean;
}
}
代码解释:
然后启动项目,控制台打印日志如下:
MyFirstJob:sayHello:Tue Aug 16 18:01:21 CST 2022
hello:sang:Tue Aug 16 18:01:22 CST 2022
hello:sang:Tue Aug 16 18:01:23 CST 2022
MyFirstJob:sayHello:Tue Aug 16 18:01:23 CST 2022
hello:sang:Tue Aug 16 18:01:24 CST 2022
hello:sang:Tue Aug 16 18:01:25 CST 2022
MyFirstJob:sayHello:Tue Aug 16 18:01:25 CST 2022
hello:sang:Tue Aug 16 18:01:26 CST 2022
hello:sang:Tue Aug 16 18:01:27 CST 2022
MyFirstJob:sayHello:Tue Aug 16 18:01:27 CST 2022
hello:sang:Tue Aug 16 18:01:28 CST 2022
hello:sang:Tue Aug 16 18:01:29 CST 2022
hello:sang:Tue Aug 16 18:01:30 CST 2022
hello:sang:Tue Aug 16 18:01:31 CST 2022
MyFirstJob 在重复了 3 次之后便不再执行,MySecondJob 则每秒执行一直,一直执行下去