Java使用Scheduled注解实现定时任务功能

简介: Java使用Scheduled注解实现定时任务功能

一、实现定时任务

1. 创建项目

这里我们只需要引入web依赖即可。

修改配置文件,避免和本地其他项目端口冲突

2. 增加注解

启动类增加注解@EnableScheduling

package com.example.scheduledemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling //添加注解
public class ScheduleDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(ScheduleDemoApplication.class, args);
    }
}

还可以新增一个配置文件,把注解放在配置类上,同时也这个类也变成了配置类,推荐这么写,这会让启动类更简洁,找配置也更好找。

package com.example.scheduledemo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
@Configuration
@EnableScheduling
public class ScheduledConfig {
}

3. 创建定时任务

我们创建一个包 job 里面存放一些定时任务类。

package com.example.scheduledemo.job;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component
public class TestJob1 {
    @Scheduled(cron = "0/5 * * * * *")  //每五秒执行一次
    public void test1(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.print("定时任务在"+ simpleDateFormat.format(new Date()) +" 执行\r\n");
    }
}

执行结果如下

这样我们就实现了最简单的定时任务。

二、配置详解

我们可以通过IDE查看注解@Scheduled的源码,根据源码我们可以看到其他参数

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package org.springframework.scheduling.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.concurrent.TimeUnit;
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {
    String CRON_DISABLED = "-";
    String cron() default "";
    String zone() default "";
    long fixedDelay() default -1L;
    String fixedDelayString() default "";
    long fixedRate() default -1L;
    String fixedRateString() default "";
    long initialDelay() default -1L;
    String initialDelayString() default "";
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
}
  • fixedDelay 上次任务结束后的延迟时间执行下次任务
  • fixedRate 上次任务开始后的延迟时间执行下次任务
  • initialDelay 第一次执行的延迟时间
  • timeUnit 时间单位,默认为毫秒

这里注意的是,fixedDelayfixedRatecron不能同时使用,initialDelay不能和cron同时使用。

三、定时任务cron表达式

这里不得不说下,源码的注释很完善,建议多读读源码,下面摘录的是源码注释的翻译。

将给定的 crontab 表达式字符串解析为 CronExpression。该字符串有六个以空格分隔的时间和日期字段:

┌────────────── 秒 (0-59)

│ ┌───────────── 分钟 (0 - 59)

│ │ ┌───────────── 小时 (0 - 23)

│ │ │ ┌───────────── 一个月中的某天 (1 - 31)

│ │ │ │ ┌───────────── 月(1-12)(或JAN-DEC)

│ │ │ │ │ ┌───────────── 星期几(0 - 7)

│ │ │ │ │ │ (0 或 7 为星期日,或 MON-SUN)

│ │ │ │ │ │


以下规则适用:

一个字段可以是一个星号 (*),它始终代表“first-last”。对于“月中的日”或“周中的日”字段,可以使用问号 (?) 代替星号。

数字范围由用连字符 (-) 分隔的两个数字表示。指定的范围包括在内。

在范围(或 *)之后,使用 /n 指定数字值在范围内的间隔。

英文名称也可用于“月”和“星期几”字段。使用特定日期或月份的前三个字母(不区分大小写)。

“day of month”和“day of week”字段可以包含一个 L 字符,代表“last”,并且在每个字段中具有不同的含义:

在“日期”字段中,L 代表“月份的最后一天”。如果后跟负偏移量(即 L-n),则表示“本月倒数第 n 天”。如果后跟 W(即 LW),则表示“本月的最后一个工作日”。

在“星期几”字段中,L 代表“星期的最后一天”。如果前缀为数字或三个字母的名称(即 dL 或 DDDL),则表示“当月 d 周(或 DDD)的最后一天”。

“day of month”字段可以是 nW,它表示“离该月 n 中最近的工作日”。如果 n 落在星期六,这将产生它之前的星期五。如果 n 落在星期日,这将产生之后的星期一,如果 n 为 1 并且落在星期六,也会发生这种情况(即 1W 代表“本月的第一个工作日”)。

“星期几”字段可以是d#n(或DDD#n),代表“该月第d周(或DDD)的第n天”。

示例表达式:

“0 0 * * * " = 每天每个小时的开头。
"
/10 * * * * *” = 每十秒。

“0 0 8-10 * * *” = 每天的 8 点、9 点和 10 点。

“0 0 6,19 * * *” = 每天早上 6:00 和晚上 7:00。

“0 0/30 8-10 * * *” = 每天 8:00、8:30、9:00、9:30、10:00 和 10:30。

“0 0 9-17 * * MON-FRI” = 工作日朝九晚五

“0 0 0 25 12 ?” = 每个圣诞节的午夜

“0 0 0 L * *” = 每月最后一天的午夜

“0 0 0 L-3 * *” = 倒数第三天午夜

“0 0 0 1W * *” = 每月第一个工作日的午夜

“0 0 0 LW * *” = 每月最后一个工作日的午夜

“0 0 0 * * 5L” = 每月最后一个星期五午夜

“0 0 0 * * THUL” = 每月最后一个星期四的午夜

“0 0 0 ? * 5#2” = 每月第二个星期五午夜

“0 0 0 ? * MON#1” = 每月第一个星期一的午夜

还支持以下宏:

“@yearly”(或“@annually”)每年运行一次,即“0 0 0 1 1 *”,

“@monthly”每月运行一次,即“0 0 0 1 * *”,

“@weekly”每周运行一次,即“0 0 0 * * 0”,

“@daily”(或“@midnight”)每天运行一次,即“0 0 0 * * *”,

“@hourly”每小时运行一次,即“0 0 * * * *”。

四、参考资料

目录
打赏
0
0
0
0
10
分享
相关文章
Java注解的底层源码剖析与技术认识
Java注解(Annotation)是Java 5引入的一种新特性,它提供了一种在代码中添加元数据(Metadata)的方式。注解本身并不是代码的一部分,它们不会直接影响代码的执行,但可以在编译、类加载和运行时被读取和处理。注解为开发者提供了一种以非侵入性的方式为代码提供额外信息的手段,这些信息可以用于生成文档、编译时检查、运行时处理等。
113 7
注解的艺术:Java编程的高级定制
注解是Java编程中的高级特性,通过内置注解、自定义注解及注解处理器,可以实现代码的高度定制和扩展。通过理解和掌握注解的使用方法,开发者可以提高代码的可读性、可维护性和开发效率。在实际应用中,注解广泛用于框架开发、代码生成和配置管理等方面,展示了其强大的功能和灵活性。
68 25
构建高效Java后端与前端交互的定时任务调度系统
通过以上步骤,我们构建了一个高效的Java后端与前端交互的定时任务调度系统。该系统使用Spring Boot作为后端框架,Quartz作为任务调度器,并通过前端界面实现用户交互。此系统可以应用于各种需要定时任务调度的业务场景,如数据同步、报告生成和系统监控等。
71 9
微信小程序与Java后端实现微信授权登录功能
微信小程序极大地简化了登录注册流程。对于用户而言,仅仅需要点击授权按钮,便能够完成登录操作,无需经历繁琐的注册步骤以及输入账号密码等一系列复杂操作,这种便捷的登录方式极大地提升了用户的使用体验
606 12
Java中简单定时任务的实现
在 Java 中实现定时任务有多种方式,每种方式的原理和适用场景不同。`java.util.Timer` 和 `TimerTask` 通过单线程执行任务,适合简单场景;`ScheduledExecutorService` 基于线程池,支持多线程并发,更加灵活和健壮;三种方式各有优劣,开发者可根据需求选择合适的方案。
|
4月前
|
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
159 34
🎉Java零基础:全面解析枚举的强大功能
【10月更文挑战第19天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
165 60
Java 中的注解(Annotations):代码中的 “元数据” 魔法
Java注解是代码中的“元数据”标签,不直接参与业务逻辑,但在编译或运行时提供重要信息。本文介绍了注解的基础语法、内置注解的应用场景,以及如何自定义注解和结合AOP技术实现方法执行日志记录,展示了注解在提升代码质量、简化开发流程和增强程序功能方面的强大作用。
201 5
|
5月前
|
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
79 2
[Java]自定义注解
本文介绍了Java中的四个元注解(@Target、@Retention、@Documented、@Inherited)及其使用方法,并详细讲解了自定义注解的定义和使用细节。文章还提到了Spring框架中的@AliasFor注解,通过示例帮助读者更好地理解和应用这些注解。文中强调了注解的生命周期、继承性和文档化特性,适合初学者和进阶开发者参考。
156 14