Spring Boot定时任务
Spring Task 定时任务
Spring Task 是 Spring Boot 内置的定时任务模块,可以满足大部分的定时任务场景需求。
通过为方法添加一个简单的注解,即可按设定的规则定时执行该方法。
@SpringBootApplication
@EnableScheduling // 开启定时任务
public class SpringBootTaskApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootTaskApplication.class, args);
}
}
定时任务方法需要在 Spring 组件类才能生效。
注意类中方法添加了 @Scheduled
注解,所以会按照 @Scheduled
注解参数指定的规则定时执行
/**
* 任务类
*/
@Component
public class MySpringTask {
/**
* 每2秒执行1次
*/
@Scheduled(fixedRate = 2000)
public void fixedRateMethod() throws InterruptedException {
System.out.println("fixedRateMethod:" + new Date());
Thread.sleep(1000);
}
}
@Scheduled
也支持使用 Cron 表达式, Cron 表达式可以非常灵活地设置定时任务的执行时间
/**
* 在每分钟的00秒执行
*/
@Scheduled(cron = "0 * * * * ?")
public void jump() throws InterruptedException {
System.out.println("心跳检测:" + new Date());
}
/**
* 在每天的00:00:00执行
*/
@Scheduled(cron = "0 0 0 * * ?")
public void stock() throws InterruptedException {
System.out.println("置满库存:" + new Date());
}
Cron 表达式并不难理解,从左到右一共 6 个位置,分别代表秒、时、分、日、月、星期,以秒为例:
- 如果该位置上是
0
,表示在第 0 秒执行; - 如果该位置上是
*
,表示每秒都会执行; - 如果该位置上是
?
,表示该位置的取值不影响定时任务,由于月份中的日和星期可能会发生意义冲突,所以日、 星期中需要有一个配置为?
。
按照上面的理解,cron = "0 * * * * ?"
表示在每分钟的 00 秒执行、cron = "0 0 0 * * ?"
表示在每天的 00:00:00 执行。
Quartz 定时任务
在企业级应用这个领域,还有更加强大灵活的 Quartz 框架可供选择
需要引入 Quartz 框架相关依赖。
实例:
<!-- Quartz -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
添加 @EnableScheduling
注解,开启定时任务功能。
实例:
@SpringBootApplication
@EnableScheduling // 开启定时任务
public class SpringBootQuartzApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootQuartzApplication.class, args);
}
}
Quartz 定时任务需要通过 Job 、 Trigger 、 JobDetail 来设置。
- Job:具体任务操作类
- Trigger:触发器,设定执行任务的时间
- JobDetail:指定触发器执行的具体任务类及方法
开发一个 Job 组件:
/**
* 打折任务
*/
@Component // 注册到容器中
public class DiscountJob {
/**
* 执行打折
*/
public void execute() {
System.out.println("更新数据库中商品价格,统一打5折");
}
}
然后在配置类中设定 Trigger 及 JobDetail 。
实例:
/**
* 定时任务配置
*/
@Configuration
public class QuartzConfig {
/**
* 配置JobDetail工厂组件,生成的JobDetail指向discountJob的execute()方法
*/
@Bean
MethodInvokingJobDetailFactoryBean jobFactoryBean() {
MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
bean.setTargetBeanName("discountJob");
bean.setTargetMethod("execute");
return bean;
}
/**
* 触发器工厂
*/
@Bean
CronTriggerFactoryBean cronTrigger() {
CronTriggerFactoryBean bean = new CronTriggerFactoryBean();
// Corn表达式设定执行时间规则
bean.setCronExpression("0 0 8 ? * 7");
// 执行JobDetail
bean.setJobDetail(jobFactoryBean().getObject());
return bean;
}
}
具体分析下上面的代码:
- 触发器设定的 Corn 表达式为
0 0 8 ? * 7
,表示每周六的 08:00:00 执行 1 次; - 触发器指定的 JobDetail 为 jobFactoryBean 工厂的一个对象,而 jobFactoryBean 指定的对象及方法为 discountJob 与 execute () ;
- 所以每周六的 8 点,就会运行 discountJob 组件的 execute () 方法 1 次;
- Corn 表达式和执行任务、方法均以参数形式存在,这就意味着我们完全可以根据文件或数据库配置动态地调整执行时间和执行的任务;