springboot实现定时任务

一、序言:

最近项目需要用到定时任务,需要完成一个定时功能。经过了解,项目中目前实现定时任务,一般有三种选择,一是用Java自带的timer类。稍微看了一下,可以实现大部分的指定频率的任务的调度(timer.schedule()),也可以实现关闭和开启(timer.cancle)。但是用其来实现某天的某个时间或者某月的某一天调度任务有点不方便。

二是采用Quartz 调度器实现。这是一个功能很强大的开源的专门用于定时任务调度的框架,也很好的和springboot整合,缺点:配置复杂,需要花费一定的时间去了解和研究。

三是spring3.0以后自带的scheduletask任务调度,可以实现quartz的大部分功能,不需要额外引用jar,也不需要另外配置。而且支持注解和配置文件两种。

我选择的是最直接简单的第三种。下面简单介绍下springboot自带的定时器来实现定时任务。

二、定时任务代码:

简单介绍:开启和关闭相当于写出一个个接口,暴露给前端,通过页面来实现定时器 的开关操作。由于我是后台开发人员,这里只给出后台代码。

1、controller层代码:


 
 
  1. package com.left.controller;
  2. import com.left.Result;
  3. import com.left.runnable.MyRunnable1;
  4. import com.left.runnable.MyRunnable2;
  5. import com.left.util.ResultUtils;
  6. import com.left.utils.YouXinConfiguration;
  7. import io.swagger.annotations.Api;
  8. import io.swagger.annotations.ApiOperation;
  9. import lombok.extern.slf4j.Slf4j;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.context.annotation.Bean;
  12. import org.springframework.scheduling.Trigger;
  13. import org.springframework.scheduling.TriggerContext;
  14. import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
  15. import org.springframework.scheduling.support.CronTrigger;
  16. import org.springframework.web.bind.annotation.PostMapping;
  17. import org.springframework.web.bind.annotation.RequestMapping;
  18. import org.springframework.web.bind.annotation.RestController;
  19. import java.util.Date;
  20. import java.util.concurrent.ScheduledFuture;
  21. /**
  22. * <pre>
  23. * @author : orange
  24. * @e-mail : 495314527@qq.com
  25. * @time : 2018/8/28 16:15
  26. * @desc : 定时任务
  27. * @version: 1.0
  28. * </pre>
  29. */
  30. @Slf4j
  31. @RestController
  32. @Api(description = "定时任务")
  33. @RequestMapping( "/quartz/task")
  34. public class DynamicTaskController {
  35. @Autowired
  36. private YouXinConfiguration youXinConfiguration;
  37. @Autowired
  38. private ThreadPoolTaskScheduler threadPoolTaskScheduler;
  39. private ScheduledFuture<?> future1;
  40. private ScheduledFuture<?> future2;
  41. @Bean
  42. public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
  43. return new ThreadPoolTaskScheduler();
  44. }
  45. @PostMapping( "/startCron1")
  46. @ApiOperation( "开始定时任务1")
  47. public Result startCron1() {
  48. future1 = threadPoolTaskScheduler.schedule( new MyRunnable1(), new Trigger(){
  49. @Override
  50. public Date nextExecutionTime(TriggerContext triggerContext){
  51. return new CronTrigger(youXinConfiguration.getCorn1()).nextExecutionTime(triggerContext);
  52. }
  53. });
  54. System.out.println( "DynamicTask.startCron1()");
  55. return ResultUtils.success();
  56. }
  57. @PostMapping( "/stopCron1")
  58. @ApiOperation( "关闭定时任务1")
  59. public Result stopCron1() {
  60. if (future1 != null) {
  61. future1.cancel( true);
  62. }
  63. System.out.println( "DynamicTask.stopCron1()");
  64. return ResultUtils.success();
  65. }
  66. @PostMapping( "/startCron2")
  67. @ApiOperation( "开始定时任务2")
  68. public Result startCron2() {
  69. future2 = threadPoolTaskScheduler.schedule( new MyRunnable2(), new Trigger(){
  70. @Override
  71. public Date nextExecutionTime(TriggerContext triggerContext){
  72. return new CronTrigger(youXinConfiguration.getCorn2()).nextExecutionTime(triggerContext);
  73. }
  74. });
  75. System.out.println( "DynamicTask.startCron2()");
  76. return ResultUtils.success();
  77. }
  78. @PostMapping( "/stopCron2")
  79. @ApiOperation( "关闭定时任务2")
  80. public Result stopCron2() {
  81. if (future2 != null) {
  82. future2.cancel( true);
  83. }
  84. System.out.println( "DynamicTask.stopCron2()");
  85. return ResultUtils.success();
  86. }
  87. }

这里面我写了两组定时器的开关操作。这层代码中所引用类的介绍:

ThreadPoolTaskScheduler:线程池任务调度类,能够开启线程池进行任务调度。ThreadPoolTaskScheduler.schedule()方法会创建一个定时计划ScheduledFuture,在这个方法需要添加两个参数,Runnable(线程接口类) 和CronTrigger(定时任务触发器)

YouXinConfiguration:自己写的读取yml文件中数据的类,我是通过这个类来读取yml文件中cron时间表达式的,从而可以达到定时时间可配置的效果。当然了也可以把这个时间表达式写成通过前端页面传入的形式。但是我觉得这种时间参数改动频率很小,写在yml配置文件足以。这个类下面会给出代码。

MyRunnable1与MyRunnable2类:这两个类都是实现了Runnable接口,重写了run方法,定时任务的逻辑代码就是在这个里面实现的。代码会在下面给出。

2、YouXinConfiguration类代码:


 
 
  1. package com.left.utils;
  2. import lombok.Data;
  3. import lombok.EqualsAndHashCode;
  4. import org.springframework.boot.context.properties.ConfigurationProperties;
  5. import org.springframework.stereotype.Component;
  6. /**
  7. * <pre>
  8. * @author : orange
  9. * @e-mail : 495314527@qq.com
  10. * @time : 2018/8/28 16:15
  11. * @desc :
  12. * @version: 1.0
  13. * </pre>
  14. */
  15. @Data
  16. @Component
  17. @ConfigurationProperties(prefix = "youxing")
  18. @EqualsAndHashCode(callSuper = false)
  19. public class YouXinConfiguration {
  20. private String corn1;
  21. private String corn2;
  22. }

3、yml文件(定时时间的配置的在最下面的youxing字段)


 
 
  1. server:
  2. port: 8002
  3. spring:
  4. application:
  5. name: dubbo-client-orange
  6. redis:
  7. database: 0
  8. host: 127.0.0.1
  9. port: 6379
  10. password:
  11. jedis:
  12. pool:
  13. max-active: 8
  14. max-wait: - 1
  15. max-idle: 8
  16. min-idle: 0
  17. timeout: 10000
  18. dubbo:
  19. server: false
  20. registry: redis: //127.0.0.1:6379
  21. consumer:
  22. check: false
  23. timeout: 10000
  24. youxing:
  25. corn1: 0/ 10 * * * * ?
  26. corn2: 0/ 5 * * * * ?

4、MyRunnable1与MyRunnable2基本一样:


 
 
  1. package com.left.runnable;
  2. import java.text.SimpleDateFormat;
  3. import java.util.Date;
  4. public class MyRunnable1 implements Runnable {
  5. @Override
  6. public void run() {
  7. System.out.println( "first DynamicTask," + new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss").format( new Date()));
  8. }
  9. }

 
 
  1. package com.left.runnable;
  2. import java.text.SimpleDateFormat;
  3. import java.util.Date;
  4. public class MyRunnable2 implements Runnable {
  5. @Override
  6. public void run() {
  7. System.out.println( "second DynamicTask," + new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss").format( new Date()));
  8. }
  9. }

5、启动SpringBoot项目,访问 http://localhost:8080/swagger-ui.html

6、控制台打印效果:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值