文章目录
- 前言
- 一、@Scheduled
- 二、Quartz
前言
定时任务是企业级开发中最常见的功能之一,如定时推送短信和邮件、数据库备份、定时统计收益、定时统计访客等,简单的定时任务可以直接通过Spring中的@Scheduled注解来实现,复杂的定时任务则可以通过集成Quartz来实现,下面分别介绍。
一、@Scheduled
@Scheduled
是Spring提供的定时任务注解,使用方便,配置简单,可以解决工作中大部分的定时任务需求,使用方式如下:
- 首先创建一个普通的Spring Boot Web工程,添加Web依赖即可,代码如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
- 然后在项目启动类上添加
@EnableScheduling
注解开启定时任务 - 定时任务主要通过
@Scheduled
注解进行配置,类上要加@Component
,代码和注释如下:
@Component
public class TestSchedule {
//其中fixedDelay = 1000表示在当前任务执行结束1秒后开启另一个任务
@Scheduled(fixedDelay = 1000)
public void testSchedule1(){
System.out.println("fixedDelay执行啦......");
}
//fixedRate = 1000表示在当前任务开始执行1秒后开启另一个定时任务
@Scheduled(fixedRate = 1000)
public void testSchedule2(){
System.out.println("fixedRate执行啦......");
}
//initialDelay = 1000则表示首次执行的延迟时间
@Scheduled(initialDelay = 1000,fixedRate = 2000)
public void testSchedule3(){
System.out.println("initialDelay执行啦......");
}
//使用cron表达式, cron = "* * * * * *"表示该定时任务每秒钟执行一次
@Scheduled(cron = "* * * * * *")
public void testSchedule4(){
System.out.println("cron执行啦......");
}
}
配置完成后,接下来启动Spring Boot项目即可,定时任务部分打印日志如图:
@Scheduled使用注意事项:如果是分布式架构,在每一台机器上都会在同时执行定时调度任务,可能产生很多重复数据或者导致系统出现其他的业务逻辑BUG,所以在使用@Scheduled进行任务调度时,一定要配合redis的分布式锁来使用,让定时调度任务只在一台机器上执行,避免BUG出现
二、Quartz
Quartz简介:
Quartz
是一个功能丰富的开源作业调度库,它由Java写成,可以集成在任何Java应用程序中,包括Java SE
和Java EE
等。使用Quartz可以创建简单或者复杂的执行计划,它支持数据库、集群、插件以及邮件,并且支持cron
表达式,具有极高的灵活性。Spring Boot中集成Quartz和Spring中集成Quartz比较类似,主要提供三个Bean:JobDetail
、Trigger
以及SchedulerFactory
。
Quartz整合Springboot
- 首先创建Spring Boot项目,添加Quartz依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
- 然后创建两个Job,代码如下:
Job可以是一个普通的JavaBean,如果是普通的JavaBean,那么可以先添加@Component
注解将之注册到Spring容器中。
@Component
public class MyFirstJob {
public void sayHello() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date now = new Date();
System.out.println("MyFirstJob:sayHello: " + sdf.format(now));
}
}
Job也可以继承抽象类QuartzJobBean
,若继承自QuartzJobBean,则需要实现该类中的executeInternal
方法,该方法在任务被调用时使用
public class MySecondJob extends QuartzJobBean {
private String name;
public void setName(String name) {
this.name = name;
}
@Override
protected void executeInternal(JobExecutionContext context) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date now = new Date();
System.out.println("hello: " + name + " : " + sdf.format(now));
}
}
- 接下来创建QuartzConfig对JobDetail和Trigger进行配置,代码如下:
@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;
}
}
代码解释:
- JobDetail的配置有两种方式:第一种方式通过
MethodInvokingJobDetailFactoryBean
类配置JobDetail,只需要指定Job的实例名和要调用的方法即可,注册这种方式无法在创建JobDetail时传递参数;第二种方式是通过JobDetailFactoryBean
来实现的,这种方式只需要指定JobClass
即可,然后可以通过JobDataMap
传递参数到Job中,Job中只需要提供属性名,并且提供一个相应的set方法即可接收到参数。 - Trigger有多种不同实现,这里展示两种常用的Trigger:
SimpleTrigger
和CronTrigger
,这两种Trigger分别使用SimpleTriggerFactoryBean
和CronTriggerFactoryBean
进行创建。在SimpleTriggerFactoryBean
对象中,首先设置JobDetail,然后通过setRepeatCount
配置任务循环次数,setStartDelay
配置任务启动延迟时间,setRepeatInterval
配置任务的时间间隔。在CronTriggerFactoryBean
对象中,则主要配置JobDetail和Cron
表达式。 - 最后通过
SchedulerFactoryBean
创建SchedulerFactory
,然后配置Trigger即可。
经过这几步的配置,定时任务就配置成功了。接下来启动Spring Boot项目,控制台打印日志如图所示: