SpringBoot 实现定时任务有两种方式,其中包括有 Scheduled 定时器
和 整合 Quartz 定时任务框架
,前者简单易上手,但功能较单一,但也能实现大部分需求,后者是一个强大的定时任务框架,但较复杂。接下来分别介绍这两种方式如何使用。
一、通过 Scheduled 定时器实现定时任务
Scheduled
是 Spring 款架提供的,自 Spring 3.0 开始就提供注解的方式实现定时任务。
1. 在 POM 文件添加 Scheduled
在 pom.xml 中加入 spring-context-support
,在此之前可以检查一下是否已经有该 JAR ,有就不需要再加了。
<!-- Scheduled 坐标 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
2. 编写定时任务类
package com.task;
import java.util.Date;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* @Description Scheduled 定时任务器
* @author 欧阳
* @since 2019年4月14日 下午2:16:42
* @version V1.0
*/
@Component
public class ScheduledDemo {
//每两秒执行一次
@Scheduled(cron = "*/2 * * * * ?")
public void scheduledMethod() {
System.out.println("Scheduled 定时器被触发:" + new Date());
}
}
使用 @Component
注解是为了让 SpringBoot 能够自动扫包时扫到,@Scheduled
支持 cron 表达式
,也支持其他属性,参考 @Scheduled
源码。 cron 表达式
表达式语法参考文章 cron 表达式详解。
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {
/**
* A cron-like expression, extending the usual UN*X definition to include
* triggers on the second as well as minute, hour, day of month, month
* and day of week. e.g. {@code "0 * * * * MON-FRI"} means once per minute on
* weekdays (at the top of the minute - the 0th second).
* @return an expression that can be parsed to a cron schedule
* @see org.springframework.scheduling.support.CronSequenceGenerator
*/
String cron() default "";
/**
* A time zone for which the cron expression will be resolved. By default, this
* attribute is the empty String (i.e. the server's local time zone will be used).
* @return a zone id accepted by {@link java.util.TimeZone#getTimeZone(String)},
* or an empty String to indicate the server's default time zone
* @since 4.0
* @see org.springframework.scheduling.support.CronTrigger#CronTrigger(String, java.util.TimeZone)
* @see java.util.TimeZone
*/
String zone() default "";
/**
* Execute the annotated method with a fixed period in milliseconds between the
* end of the last invocation and the start of the next.
* @return the delay in milliseconds
*/
long fixedDelay() default -1;
/**
* Execute the annotated method with a fixed period in milliseconds between the
* end of the last invocation and the start of the next.
* @return the delay in milliseconds as a String value, e.g. a placeholder
* or a {@link java.time.Duration#parse java.time.Duration} compliant value
* @since 3.2.2
*/
String fixedDelayString() default "";
/**
* Execute the annotated method with a fixed period in milliseconds between
* invocations.
* @return the period in milliseconds
*/
long fixedRate() default -1;
/**
* Execute the annotated method with a fixed period in milliseconds between
* invocations.
* @return the period in milliseconds as a String value, e.g. a placeholder
* or a {@link java.time.Duration#parse java.time.Duration} compliant value
* @since 3.2.2
*/
String fixedRateString() default "";
/**
* Number of milliseconds to delay before the first execution of a
* {@link #fixedRate()} or {@link #fixedDelay()} task.
* @return the initial delay in milliseconds
* @since 3.2
*/
long initialDelay() default -1;
/**
* Number of milliseconds to delay before the first execution of a
* {@link #fixedRate()} or {@link #fixedDelay()} task.
* @return the initial delay in milliseconds as a String value, e.g. a placeholder
* or a {@link java.time.Duration#parse java.time.Duration} compliant value
* @since 3.2.2
*/
String initialDelayString() default "";
}
3. 启动类中开启定时任务的使用
在启动类上加上注解 @EnableScheduling
开启定时任务的使用。
package com;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* @Description 第一个SpringBoot 应用启动类
* @author 欧阳
* @since 2019年4月3日 下午6:14:39
* @version V1.0
*/
@SpringBootApplication
@EnableScheduling
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
二、通过整合 Quartz 框架实现定时任务
Quartz 官网:http://www.quartz-scheduler.org/
使用 Quartz 分为三步:
a. 创建 Job - 任务(要做什么事?)
b. 创建 Trigger - 触发器 (什么时候去做?)
c. 创建 Scheduler - 任务调度(什么时候去做什么事?)
1. 在 POM 文件添加 Quartz
在 pom.xml 文件添加 Quartz
<!-- 添加 quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
2. 创建 Job 类
创建一个实现 Job 接口的 Job 类
package com.task;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
* @Description 定义任务类
* @author 欧阳
* @since 2019年4月14日 下午6:05:13
* @version V1.0
*/
public class QuartzDemo implements Job {
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
System.out.println("Execute:" + new Date());
}
}
3. 编写 Quartz 的启动类,注入 Spring 容器
Trigger 有 SimpleTriggerFactoryBean
,CronTriggerFactoryBean
等,SimpleTriggerFactoryBean
简单的 Trigger ,可通过其中方法设置什么时候做,而 CronTriggerFactoryBean
通过设置 cron 表达式
来设置什么时候做。cron 表达式
表达式语法参考文章 cron 表达式详解。
package com.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import com.task.QuartzDemo;
/**
* @Description Quartz 配置类
* @author 欧阳
* @since 2019年4月14日 下午6:07:01
* @version V1.0
*/
@Configuration
public class QuartzConfig {
/**
* 1.创建 Job 对象
*/
@Bean
public JobDetailFactoryBean jobDetailFactoryBean() {
JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
// 关联Job 类
jobDetailFactoryBean.setJobClass(QuartzDemo.class);
return jobDetailFactoryBean;
}
/**
* 2.创建 Trigger 对象
*/
@Bean
public CronTriggerFactoryBean cronTriggerFactoryBeanBean(JobDetailFactoryBean jobDetailFactoryBean) {
CronTriggerFactoryBean cronTriggerFactoryBeanBean = new CronTriggerFactoryBean();
// 关联 JobDetail 对象
cronTriggerFactoryBeanBean.setJobDetail(jobDetailFactoryBean.getObject());
// 每两秒执行一次
cronTriggerFactoryBeanBean.setCronExpression("*/2 * * * * ?");
return cronTriggerFactoryBeanBean;
}
/**
* 3.创建 Scheduler 对象
*/
@Bean
public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactoryBeanBean) {
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
// 关联 trigger
schedulerFactoryBean.setTriggers(cronTriggerFactoryBeanBean.getObject());
return schedulerFactoryBean;
}
}
4. 启动类中开启定时任务的使用
在启动类上加上注解 @EnableScheduling
开启定时任务的使用。
package com;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* @Description 第一个SpringBoot 应用启动类
* @author 欧阳
* @since 2019年4月3日 下午6:14:39
* @version V1.0
*/
@SpringBootApplication
@EnableScheduling
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}