Java下SpringBoot创建定时任务详解

 更新时间:2020年07月23日 10:57:45   作者:淼淼之森  
这篇文章主要介绍了Java下SpringBoot创建定时任务详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

序言

使用SpringBoot创建定时任务非常简单,目前主要有以下三种创建方式:

  • 一、基于注解(@Scheduled)
  • 二、基于接口(SchedulingConfigurer) 前者相信大家都很熟悉,但是实际使用中我们往往想从数据库中读取指定时间来动态执行定时任务,这时候基于接口的定时任务就派上用场了。
  • 三、基于注解设定多线程定时任务

一、静态:基于注解

基于注解@Scheduled默认为单线程,开启多个任务时,任务的执行时机会受上一个任务执行时间的影响。

1、创建定时器

使用SpringBoot基于注解来创建定时任务非常简单,只需几行代码便可完成。代码如下:

@Configuration //1.主要用于标记配置类,兼备Component的效果。
@EnableScheduling // 2.开启定时任务
public class SaticScheduleTask {
 //3.添加定时任务
 @Scheduled(cron = "0/5 * * * * ?")
 //或直接指定时间间隔,例如:5秒
 //@Scheduled(fixedRate=5000)
 private void configureTasks() {
 System.err.println("执行静态定时任务时间: " + LocalDateTime.now());
 }
}

Cron表达式参数分别表示:

  • 秒(0~59) 例如0/5表示每5秒
  • 分(0~59)
  • 时(0~23)
  • 日(0~31)的某天,需计算
  • 月(0~11)周几( 可填1-7 或 SUN/MON/TUE/WED/THU/FRI/SAT)

@Scheduled:除了支持灵活的参数表达式cron之外,还支持简单的延时操作,例如 fixedDelay ,fixedRate 填写相应的毫秒数即可。

2、启动测试

启动应用,可以看到控制台打印出如下信息:


显然,使用@Scheduled 注解很方便,但缺点是当我们调整了执行周期的时候,需要重启应用才能生效,这多少有些不方便。为了达到实时生效的效果,可以使用接口来完成定时任务。

二、动态:基于接口

基于接口(SchedulingConfigurer)

1、导入依赖包

<parent>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter</artifactId>
 <version>2.0.4.RELEASE</version>
 </parent>

 <dependencies>
 <dependency><!--添加Web依赖 -->
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
 </dependency>
 <dependency><!--添加MySql依赖 -->
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
 </dependency>
 <dependency><!--添加Mybatis依赖 配置mybatis的一些初始化的东西-->
  <groupId>org.mybatis.spring.boot</groupId>
  <artifactId>mybatis-spring-boot-starter</artifactId>
  <version>1.3.1</version>
 </dependency>
 <dependency><!-- 添加mybatis依赖 -->
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.4.5</version>
  <scope>compile</scope>
 </dependency>
 </dependencies>

2、添加数据库记录:

开启本地数据库mysql,随便打开查询窗口,然后执行脚本内容,如下:

DROP DATABASE IF EXISTS `socks`;
CREATE DATABASE `socks`;
USE `SOCKS`;
DROP TABLE IF EXISTS `cron`;
CREATE TABLE `cron` (
 `cron_id` varchar(30) NOT NULL PRIMARY KEY,
 `cron` varchar(30) NOT NULL 
);
INSERT INTO `cron` VALUES ('1', '0/5 * * * * ?');


然后在项目中的application.yml 添加数据源:

spring:
 datasource:
 url: jdbc:mysql://localhost:3306/socks
 username: root
 password: 123456

3、创建定时器

数据库准备好数据之后,我们编写定时任务,注意这里添加的是TriggerTask,目的是循环读取我们在数据库设置好的执行周期,以及执行相关定时任务的内容。
具体代码如下:

@Configuration //1.主要用于标记配置类,兼备Component的效果。
@EnableScheduling // 2.开启定时任务
public class DynamicScheduleTask implements SchedulingConfigurer {

 @Mapper
 public interface CronMapper {
 @Select("select cron from cron limit 1")
 public String getCron();
 }

 @Autowired //注入mapper
 @SuppressWarnings("all")
 CronMapper cronMapper;

 /**
 * 执行定时任务.
 */
 @Override
 public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {

 taskRegistrar.addTriggerTask(
  //1.添加任务内容(Runnable)
  () -> System.out.println("执行动态定时任务: " + LocalDateTime.now().toLocalTime()),
  //2.设置执行周期(Trigger)
  triggerContext -> {
   //2.1 从数据库获取执行周期
   String cron = cronMapper.getCron();
   //2.2 合法性校验.
   if (StringUtils.isEmpty(cron)) {
   // Omitted Code ..
   }
   //2.3 返回执行周期(Date)
   return new CronTrigger(cron).nextExecutionTime(triggerContext);
  }
 );
 }

}

4、启动测试

启动应用后,查看控制台,打印时间是我们预期的每10秒一次:

然后打开Navicat ,将执行周期修改为每6秒执行一次,如图:


查看控制台,发现执行周期已经改变,并且不需要我们重启应用,十分方便。如图:


注意:如果在数据库修改时格式出现错误,则定时任务会停止,即使重新修改正确;此时只能重新启动项目才能恢复。

三、多线程定时任务

基于注解设定多线程定时任务

1、创建多线程定时任务

//@Component注解用于对那些比较中立的类进行注释;
//相对与在持久层、业务层和控制层分别采用 @Repository、@Service 和 @Controller 对分层中的类进行注释
@Component
@EnableScheduling // 1.开启定时任务
@EnableAsync // 2.开启多线程
public class MultithreadScheduleTask {

 @Async
 @Scheduled(fixedDelay = 1000) //间隔1秒
 public void first() throws InterruptedException {
  System.out.println("第一个定时任务开始 : " + LocalDateTime.now().toLocalTime() + "\r\n线程 : " + Thread.currentThread().getName());
  System.out.println();
  Thread.sleep(1000 * 10);
 }

 @Async
 @Scheduled(fixedDelay = 2000)
 public void second() {
  System.out.println("第二个定时任务开始 : " + LocalDateTime.now().toLocalTime() + "\r\n线程 : " + Thread.currentThread().getName());
  System.out.println();
 }
 }

注: 这里的@Async注解很关键

2、启动测试

启动应用后,查看控制台:


从控制台可以看出,第一个定时任务和第二个定时任务互不影响;

并且,由于开启了多线程,第一个任务的执行时间也不受其本身执行时间的限制,所以需要注意可能会出现重复操作导致数据异常。

到此这篇关于Java下SpringBoot创建定时任务详解的文章就介绍到这了,更多相关SpringBoot创建定时任务内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Intellij IDEA 2019 最新乱码问题及解决必杀技(必看篇)

    Intellij IDEA 2019 最新乱码问题及解决必杀技(必看篇)

    大家在使用Intellij IDEA 的时候会经常遇到各种乱码问题,今天小编给大家分享一些关于Intellij IDEA 2019 最新乱码问题及解决必杀技,感兴趣的朋友跟随小编一起看看吧
    2020-04-04
  • Java Agent探针技术详解示例

    Java Agent探针技术详解示例

    这篇文章主要介绍了Java Agent 探针技术详情,Java 中的 Agent 技术可以让我们无侵入性的去进行代理,最常用于程序调试、热部署、性能诊断分析等场景,下文更多相关资料,感兴趣的小伙伴可以参考一下
    2022-06-06
  • IDEA2023常用配置指南(JDK/系统设置等常用配置)

    IDEA2023常用配置指南(JDK/系统设置等常用配置)

    idea很强大,但是初次安装默认的有很多设置并不是满足我们开发的需要,下面这篇文章主要给大家介绍了关于IDEA2023常用配置(JDK/系统设置等常用配置)的相关资料,需要的朋友可以参考下
    2023-12-12
  • Java中clone方法使用笔记

    Java中clone方法使用笔记

    clone顾名思义是复制,在Java语言中,clone方法被对象调用,所以会复制对象,下面这篇文章主要给大家介绍了关于Java中clone方法使用的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-02-02
  • 从0构建Oauth2Server服务之Refreshing-access-tokens

    从0构建Oauth2Server服务之Refreshing-access-tokens

    这篇文章主要为大家介绍了从0构建Oauth2Server服务之Refreshing-access-tokens刷新令牌示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • SpringBoot导入mail依赖报错问题解决

    SpringBoot导入mail依赖报错问题解决

    这篇文章主要介绍了SpringBoot导入mail依赖报错问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • Mybatis批量修改的操作代码

    Mybatis批量修改的操作代码

    这篇文章主要介绍了Mybatis批量修改的操作代码,包括整体批量修改的详细代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2017-09-09
  • Java面向对象之包装类的用途与实际使用

    Java面向对象之包装类的用途与实际使用

    所谓包装类,就是能够直接将简单类型的变量表示为一个类,在执行变量类型的相互转换时,我们会大量使用这些包装类,本文我们来深入探索一下Java包装类的相关内容,需要的朋友可以参考下
    2022-03-03
  • Java变量命名规则详解及常见命名错误(建议收藏)

    Java变量命名规则详解及常见命名错误(建议收藏)

    这篇文章主要介绍了Java中变量命名的规则及最佳实践,包括有效字符、大小写敏感性、不能使用保留字、驼峰命名法、描述性命名、特定类型的命名习惯、避免潜在问题、常见命名错误及如何避免等内容,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-02-02
  • 利用Lambda表达式创建新线程案例

    利用Lambda表达式创建新线程案例

    这篇文章主要介绍了利用Lambda表达式创建新线程案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08

最新评论