SpringBoot中使用@Scheduled注解创建定时任务的实现

在项目日常开发过程中,经常需要定时任务来帮我们做一些工作,如清理日志。定时任务的实现方法主要有 Timer、Quartz 以及 elastic-job

Timer 实现定时任务

只执行一次的定时任务

Timer timer = new Timer();
timer.schedule(new TimerTask() {
 @Override
 public void run() {
  System.out.println("2000毫米后执行一次。");
 }
}, 2000);

timer.schedule(new TimerTask() {
 @Override
 public void run() {
  System.out.println("5000毫米后执行一次。");
 }
}, new Date(System.currentTimeMillis() + 5000));

循环执行任务

Timer timer = new Timer();
timer.schedule(new TimerTask() {
 @Override
 public void run() {
  System.out.println(111);
 }
}, 1000, 2000); // 1000毫米后执行第一次,之后每2000毫米执行一次

终止任务

timer.concel();

Timer 是 JDK 实现的定时任务,用起来简单、方便,对一些简单的定时任务可以使用它。由于它不支持 cron 表达式,现在已经很少用了。

Quartz 实现定时任务

Quartz 是一个完全由 Java 编写的开源作业调度框架,可以用它来实现定时任务。

在 pom.xml 文件添加 Quartz 依赖

<dependency>
 <groupId>org.quartz-scheduler</groupId>
 <artifactId>quartz</artifactId>
 <version>2.2.1</version>
</dependency>
<dependency>
 <groupId>org.quartz-scheduler</groupId>
 <artifactId>quartz-jobs</artifactId>
 <version>2.2.1</version>
</dependency>

<dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-api</artifactId>
 <version>1.7.25</version>
</dependency>

<dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-simple</artifactId>
 <version>1.7.6</version>
</dependency>

编写 Job

定时执行的任务

public class QuartzJob implements Job{

 public void execute(JobExecutionContext context) throws JobExecutionException {
  JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
  String hello = (String) jobDataMap.get("hello");
  System.err.println(hello);
 }

}

编写 Task

public void task() {
 // 该 map 可在 job 中获取
 JobDataMap map = new JobDataMap();
 map.put("hello", "world");

 JobDetail jobDetail = newJob(QuartzJob.class).
   withIdentity("myJob", "myGroup").
   setJobData(map).build();
 /*
  * 简单定时器
  *
  * 执行时间间隔
  * withIntervalInMilliSeconds 毫秒
  * withIntervalInSeconds 秒
  * withIntervalInMinutes 分钟
  * withIntervalInHours 小时
  *
  * 执行次数
  * repeatForever 重复执行
  * withRepeatCount 次数
  */
 SimpleScheduleBuilder scheduleBuilder = simpleSchedule().withIntervalInSeconds(3).withRepeatCount(10);

 /*
  * corn定时器
  *
  * corn表达式,使用更灵活
  * corn表达式在线生成 http://cron.qqe2.com/
  */
 CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0 0 0 1 * ?");

 Trigger trigger = newTrigger().startAt(new Date()).//startNow() 默认现在开始
   withIdentity("myTrigger", "myGroup").
   //withSchedule(scheduleBuilder).build();
   withSchedule(cronScheduleBuilder).build();

 try {
  //1.创建Scheduler工厂
  SchedulerFactory schedulerFactory = new StdSchedulerFactory();
  //2.获取实例
  Scheduler scheduler = schedulerFactory.getScheduler();
  //3.设置jobDetail详情和trigger触发器
  scheduler.scheduleJob(jobDetail, trigger);
  //4.定时任务开始
  scheduler.start();
 } catch (SchedulerException e) {
  e.printStackTrace();
 }

}

在项目启动的时候调用 task 方法即可启动定时任务。

Spring Boot 创建定时任务

Spring Boot 默认已经实现了定时任务,只需要添加相应的注解即可完成

pom.xml 文件配置

pom.xml 不需要添加其他依赖,只需要加入 Spring Boot 依赖即可,这里我们添加一个 web 和 test 的依赖

<dependencies>
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
 </dependency>
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-test</artifactId>
 <scope>test</scope>
 </dependency>
  <dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-devtools</artifactId>
  <optional>true</optional>
 </dependency>
</dependencies>

在启动类上面加上 @EnableScheduling 注解

在启动类上面加上 @EnableScheduling 注解即可开启定时任务

@EnableScheduling
@SpringBootApplication
public class SchedulingApplication {

 public static void main(String[] args) {
 SpringApplication.run(SchedulingApplication.class, args);
 }
}

编写定时任务

@Component
public class ScheduledTask {

 @Scheduled(initialDelay=1000, fixedDelay = 1000)
 public void task1() {
  System.out.println("延迟1000毫秒后执行,任务执行完1000毫秒之后执行!");
  try {
   Thread.sleep(2000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }

 @Scheduled(fixedRate = 2000)
 public void task2() {
  System.out.println("延迟1000毫秒后执行,之后每2000毫秒执行一次!");
 }

}

除了这些还支持 cron 表达式

@Scheduled(cron = "*/2 * * * * ?")
public void task3() {
 System.out.println("每2秒执行一次!");
}

启动 Spring Boot 项目在控制台就会看到任务定时执行

cron 表达式

以下是 cron 表达式的的两种语法

Seconds Minutes Hours DayofMonth Month DayofWeek Year
Seconds Minutes Hours DayofMonth Month DayofWeek

每一个域可出现的字符如下:

  • Seconds:可出现", - * /"四个字符,有效范围为0-59的整数
  • Minutes:可出现", - * /"四个字符,有效范围为0-59的整数
  • Hours:可出现", - * /"四个字符,有效范围为0-23的整数
  • DayofMonth:可出现", - * / ? L W C"八个字符,有效范围为0-31的整数
  • Month:可出现", - * /"四个字符,有效范围为1-12的整数或JAN-DEc
  • DayofWeek:可出现", - * / ? L C #"四个字符,有效范围为1-7的整数或SUN-SAT两个范围。1表示星期天,2表示星期一, 依次类推
  • Year:可出现", - * /"四个字符,有效范围为1970-2099年

举几个例子

*/2 * * * * ? 表示每2秒执行一次!
0 0 2 1 * ? * 表示在每月的1日的凌晨2点调度任务
0 15 10 ? * MON-FRI 表示周一到周五每天上午10:15执行作业
0 15 10 ? 6L 2002-2006 表示2002-2006年的每个月的最后一个星期五上午10:15执行作

推荐一个 cron 表达式在线生成工具

http://tools.jb51.net/code/Quartz_Cron_create

参考资料

本文所有代码放在 Github

到此这篇关于SpringBoot中使用@Scheduled注解创建定时任务的实现的文章就介绍到这了,更多相关SpringBoot创建定时任务内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Springboot通过Scheduled实现定时任务代码

    定时任务一般会存在中大型企业级项目中,为了减少服务器.数据库的压力往往会采用时间段性的去完成某些业务逻辑.比较常见的就是金融服务系统推送回调,一般支付系统订单在没有收到成功的回调返回内容时会持续性的回调,这种回调一般都是定时任务来完成的.还有就是报表的生成,我们一般会在客户访问量过小的时候来完成这个操作,那往往都是在凌晨.这时我们也可以采用定时任务来完成逻辑.SpringBoot为我们内置了定时任务,我们只需要一个注解就可以开启定时为我们所用了. 在开发中,定时任务是常见的功能,在spring

  • springboot 定时任务@Scheduled实现解析

    这篇文章主要介绍了springboot 定时任务@Scheduled实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.pom.xml中导入必要的依赖: <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version&g

  • 详解SpringBoot开发案例之整合定时任务(Scheduled)

    来来来小伙伴们,基于上篇的邮件服务,定时任务就不单独分项目了,天然整合进了邮件服务中. 不知道,大家在工作之中,经常会用到那些定时任务去执行特定的业务,这里列举一下我在工作中曾经使用到的几种实现. 任务介绍 Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务.Timer的优点在于简单易用:缺点是Timer的所有任务都是由同一个线程调度的,因此所有任务都是串行执行的.同一时间只能有一个任务在执行,前一个任务的延迟或异常都将会影响到之后的任

  • SpringBoot中使用@Scheduled注解创建定时任务的实现

    在项目日常开发过程中,经常需要定时任务来帮我们做一些工作,如清理日志.定时任务的实现方法主要有 Timer.Quartz 以及 elastic-job Timer 实现定时任务 只执行一次的定时任务 Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { System.out.println("2000毫米后执行一次."); } }, 2000); timer.s

  • 解决SpringBoot中的Scheduled单线程执行问题

    目录 问题描述 原因分析: 解决方案: 补充: 问题描述 在一次SpringBoot中使用Scheduled定时任务时,发现某一个任务出现执行占用大量资源,会导致其他任务也执行失败.类似于以下模拟场景,test1定时任务模拟有五秒钟执行时间,这时会同步影响到test2任务的执行,导致test2任务也变成五秒执行一次. @Scheduled(fixedRate = 1000) public void test1() throws InterruptedException { log.info(Th

  • Linux中使用crond工具创建定时任务的方法

    前言 crond是一个linux下的定时执行工具(相当于windows下的scheduled task),可以在无需人工干预的情况下定时地运行任务.crond工具提供crontab命令来设置定时任务,属于守护进程,只能精确到分钟,可以设定周期性执行Linux命令或者Shell脚本,每分钟crond都会检查是否有定时任务需要执行 本次实验系统为CentOS 7 操作步骤 (1) 检查crond工具是否安装 yum list installed | grep crontabs 若未安装,则使用如下所

  • 解决SpringBoot中使用@Async注解失效的问题

    错误示例,同一个类中使用异步方法: package com.xqnode.learning.controller; import com.fasterxml.jackson.core.JsonProcessingException; import org.springframework.scheduling.annotation.Async; import org.springframework.web.bind.annotation.GetMapping; import org.springf

  • 详解SpringBoot中添加@ResponseBody注解会发生什么

    SpringBoot版本2.2.4.RELEASE. [1]SpringBoot接收到请求 ① springboot接收到一个请求返回json格式的列表,方法参数为JSONObject 格式,使用了注解@RequestBody 为什么这里要说明返回格式.方法参数.参数注解?因为方法参数与参数注解会影响你使用不同的参数解析器与后置处理器!通常使用WebDataBinder进行参数数据绑定结果也不同. 将要调用的目标方法如下: @ApiOperation(value="分页查询") @Re

  • java使用@Scheduled注解执行定时任务

    前言 在写项目的时候经常需要特定的时间做一些特定的操作,尤其是游戏服务器,维护线程之类的,这时候就需要用到定时器. 如果此时你刚好用的是spring的话,哪么@Scheduled注解是非常好用的. 使用spring @Scheduled注解执行定时任务: 1,在spring-MVC.xml文件中进行配置 2,直接在代码控制层使用即可 package xkhd.game.fix; import org.springframework.beans.factory.annotation.Autowir

  • springboot中使用@Transactional注解事物不生效的坑

    一:在springboot中使用事物遇到的坑 1.我们知道spring中的事物分为两种:一种是编程式事物,一种是声明式事物.顾名思义,编程式事物是指通过代码去实现事物管理,这里不做过多说明.另一种是声明式事物,分为两种情况01:一种是通过传统xml方式配置,02:使用@Transaction注解方式配置,这是主要讲解的是通过注解方式配置.因为在springboot项目中,会自动配置DataSourceTransactionManager,我们只需要在对应的方法上或者类上加上@Transactio

  • 详解SpringBoot中@NotNull,@NotBlank注解使用

    目录 一.添加依赖 二.在类中使用验证注解 1.创建验证实体类(嵌套使用) 2.创建全局异常处理器,对message信息进行处理,并返回给前端 3.在controller中的使用 三.在方法参数中使用验证注解,与@RequsetParam注解同时使用,注意类上使用@Validated 四.自定义验证注解 一.添加依赖 <!-- spring-boot 2.3及以上的版本只需要引入下面的依赖 --> <dependency> <groupId>org.springfram

  • SpringBoot中使用@scheduled定时执行任务的坑

    目录 解决办法 1.将@Scheduled注释的方法内部改成异步执行 2.把Scheduled配置成成多线程执行 要注意什么坑 不绕弯子了,直接说这个坑是啥: SpringBoot使用@scheduled定时执行任务的时候是在一个单线程中,如果有多个任务,其中一个任务执行时间过长,则有可能会导致其他后续任务被阻塞直到该任务执行完成.也就是会造成一些任务无法定时执行的错觉 可以通过如下代码进行测试:     @Scheduled(cron = "0/1 * * * * ? ")    

  • 我劝你谨慎使用Spring中的@Scheduled注解

    目录 引言 1.@Scheduled失效原因 2.解析流程图 3.使用新的方法 schedule定时任务修改表达式无效 引言 在一些业务场景中需要执行定时操作来完成一些周期性的任务,比如每隔一周删除一周前的某些历史数据以及定时进行某项检测任务等等. 在日常开发中比较简单的实现方式就是使用Spring的@Scheduled(具体使用方法不再赘述)注解. 但是在修改服务器时间时会导致定时任务不执行情况的发生,解决的办法是当修改服务器时间后,将服务进行重启就可以避免此现象的发生. 本文将主要探讨服务器

随机推荐