SpringBoot如何实现定时任务(上)

电子说

1.3w人已加入

描述

SpringBoot创建定时任务的方式很简单,主要有两种方式:一、基于注解的方式(@Scheduled)二、数据库动态配置。实际开发中,第一种需要在代码中写死表达式,如果修改起来,又得重启会显得很麻烦;所以我们往往会采取第二种方式,可以直接从数据库中读取定时任务的指定执行时间,无需重启。

下面就来介绍下这两种方式吧

一、基于注解(@Scheduled)

基于注解是一种静态的方式,只需要几行代码就可以搞定了

添加一个配置类

@Configuration  //标记配置类
 @EnableScheduling   //开启定时任务
 public class MyScheduleConfig {
 
     //添加定时任务
     @Scheduled(cron = "0/5 * * * * ?")
     private void myTasks() {
         System.out.println("执行定时任务 " + LocalDateTime.now());
     }
 }

上面代码的cron表达式表示每5秒执行一次,可以通过这个网站(https://qqe2.com/cron)去生成要的cron表达式

启动应用,控制台看效果

Boot

这个方式的确很简单方便,但前面介绍也说到了,有个缺点就是当我们需要去修改定时任务的执行周期或者停止的时候,我们需要到代码层去修改,重启。

二、数据库动态配置

这里使用MySQL数据库

1、表数据添加,资源配置

1.1 添加表

CREATE TABLE `scheduled_job` (
  `job_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `job_key` varchar(128) NOT NULL COMMENT '定时任务完整类名',
  `cron_expression` varchar(20) NOT NULL COMMENT 'cron表达式',
  `task_explain` varchar(50) NOT NULL DEFAULT '' COMMENT '任务描述',
  `status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '状态,1:正常;-1:停用',
  PRIMARY KEY (`job_id`),
  UNIQUE KEY `job_key` (`job_key`),
  UNIQUE KEY `cron_key_unique_idx` (`job_key`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='定时任务表';

1.2 插入两条数据,job_key根据是完整的类名

Boot

1.3 引入依赖

<dependency>
            <groupId>org.springframework.boot<span class="hljs-name"groupId>
            <artifactId>spring-boot-starter-web<span class="hljs-name"artifactId>
        <span class="hljs-name"dependency>
        
        <dependency>
            <groupId>mysql<span class="hljs-name"groupId>
            <artifactId>mysql-connector-java<span class="hljs-name"artifactId>
            <version>5.1.49<span class="hljs-name"version>
            <scope>runtime<span class="hljs-name"scope>
        <span class="hljs-name"dependency>
        
        <dependency>
            <groupId>com.baomidou<span class="hljs-name"groupId>
            <artifactId>mybatis-plus-boot-starter<span class="hljs-name"artifactId>
            <version>3.3.1.tmp<span class="hljs-name"version>
        <span class="hljs-name"dependency>
        
        <dependency>
            <groupId>org.projectlombok<span class="hljs-name"groupId>
            <artifactId>lombok<span class="hljs-name"artifactId>
            <version>1.18.20<span class="hljs-name"version>
            <scope>provided<span class="hljs-name"scope>
        <span class="hljs-name"dependency>

1.4 配置application.yml

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/test?userUnicode=true&characterEncoding=UTF8&useSSL=false
    username: root
    password: 123
    driver-class-name: com.mysql.jdbc.Driver
server:
  servlet:
    context-path: /demo
  port: 8888

2、疯狂贴代码

2.1 创建定时任务线程池

@Configuration
 @Slf4j
 public class ScheduledConfig {
 
     @Bean
     public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
         log.info("创建定时任务调度线程池 start");
         ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
         threadPoolTaskScheduler.setPoolSize(20);
         threadPoolTaskScheduler.setThreadNamePrefix("taskExecutor-");
         threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true);
         threadPoolTaskScheduler.setAwaitTerminationSeconds(60);
         log.info("创建定时任务调度线程池 end");
         return threadPoolTaskScheduler;
     }
 
 }

2.2 项目启动时初始化定时任务

@Slf4j
 @Component
 public class ScheduledTaskRunner implements ApplicationRunner {
     @Autowired
     private ScheduledTaskService scheduledTaskService;
 
     @Override
     public void run(ApplicationArguments args) throws Exception {
         log.info("----初始化定时任务开始----");
         scheduledTaskService.initTask();
         log.info("----初始化定时任务完成----");
     }
 }

2.3 定时任务公共接口

public interface ScheduledOfTask extends Runnable{
 
     void execute();
 
     @Override
     default void run() {
         execute();
     }
 }

2.4 创建两个定时任务实现类

@Component
 @Slf4j
 public class TaskJob1 implements ScheduledOfTask{
     @Override
     public void execute() {
         log.info("执行任务1 "+ LocalDateTime.now());
     }
 }
@Component
 @Slf4j
 public class TaskJob2 implements ScheduledOfTask{
     @Override
     public void execute() {
         log.info("执行任务2 "+ LocalDateTime.now());
     }
 }

2.5 定时任务管理接口

public interface ScheduledTaskService{
 
     Boolean start(ScheduledJob scheduledJob);
 
     Boolean stop(String jobKey);
 
     Boolean restart(ScheduledJob scheduledJob);
 
     void initTask();
 }
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分