首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >原创 | Springboot任务

原创 | Springboot任务

作者头像
润森
发布2020-01-14 15:28:52
3540
发布2020-01-14 15:28:52
举报
文章被收录于专栏:毛利学Python毛利学Python

大家好,我是润森。期末已挂,谁来烧纸,挂得我又有动力学习了!

任务

什么叫做任务呢?其实就是类中实现了一个什么功能的方法。

常见的任务就是异步任务,定时任务

异步任务:其实就是一个很特别的方法,这个方法没有返回值(也可以有返回值,后面会说的),但是方法内部的逻辑会耗费很多时间!例如,用户请求每次到controller,要执行到这个异步方法的时候,我们只需要命令一个空闲状态的线程去执行它即可,由于没有返回值不影响后续代码的运行,controller直接去执行后续的代码。这样可以极为迅速的响应用户,用户体验非常好。

异步任务

目录如下

AsyncService.java
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

/**
 * @author: 毛利
 */
@Service
public class AsyncService {
    //告诉Spring这是一个异步方法
    @Async
    public void hello() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("处理数据中...");
    }
    
}
AsyncController
@RestController
public class AsyncController {
	
    @Autowired
    AsyncService asyncService;

    @GetMapping("/hello")
    public String hello() {
        asyncService.hello();
        return "success";
    }
}

在Spring中可以在方法上添加@Async注释,以便异步调用该方法。换句话说,调用者将在调用含有@Async注释的方法时立即返回,并且该方法的实际执行将发生在Spring TaskExecutor异步处理器线程中。需要注意的是该注解@Async默认是不会解析的,SpringBoot中需要加上@EnableAsync来启动。

@EnableAsync
@SpringBootApplication
public class TaskApplication {
    public static void main(String[] args) {
        SpringApplication.run(TaskApplication.class, args);
    }
}

访问hello请求无需等待3秒钟

定时任务

在我们平时开发的项目中,定时任务基本属于必不可少的功能,那大家都是怎么做的呢?但我知道的大多都是静态定时任务实现。

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

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

@Service
@Component
public class ScheduledService {

    /**
     * second(秒), minute(分), hour(时), day of month(日), month(月), day of week(周几).
     * 0 * * * * MON-FRI
     * 【0 0/5 14,18 * * ?】 每天14点整,和18点整,每隔5分钟执行一次
     * 【0 15 10 ? * 1-6】 每个月的周一至周六10:15分执行一次
     * 【0 0 2 ? * 6L】每个月的最后一个周六凌晨2点执行一次
     * 【0 0 2 LW * ?】每个月的最后一个工作日凌晨2点执行一次
     * 【0 0 2-4 ? * 1#1】每个月的第一个周一凌晨2点到4点期间,每个整点都执行一次;
     */
    // @Scheduled(cron = "0 * * * * MON-SAT")
    //@Scheduled(cron = "0,1,2,3,4 * * * * MON-SAT")
    // @Scheduled(cron = "0-4 * * * * MON-SAT")
    @Scheduled(cron = "0/5 * * * * *") // 每5秒跑一次
    public void hello() {
        System.out.println("hello ... ");
    }

}

通过在任意类上使用注解@EnableScheduling开启定时任务功能(依笔者最近所用,凡是@Enable开头的貌似都是开启某项功能的注解),开启后可以在任一需要定时执行的方法上使用注解@Scheduled完成配置,项目启动后即可自动按需要执行

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;


@EnableAsync
@EnableScheduling //开启基于注解的定时任务
@SpringBootApplication
public class TaskApplication {

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

}

Spring Scheduler定时任务使用步骤:

(1)启用对Spring Scheduler的支持:只需要在启动类或者配置类添加

@EnableScheduling;

(2)定义一个Task服务,在类上添加注解:@Component;

(3)创建定时任务:添加方法使用@Scheduled创建定时任务;

Cron表达式

Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式

(1) Seconds Minutes Hours DayofMonth Month DayofWeek Year

(2)Seconds Minutes Hours DayofMonth Month DayofWeek

一、结构

corn从左到右(用空格隔开):秒 分 小时 月份中的日期 月份 星期中的日期 年份

二、各字段的含义

字段

允许值

允许的特殊字符

秒(Seconds)

0~59的整数

, - * / 四个字符

分(Minutes)

0~59的整数

,- * / 四个字符

小时(Hours

0~23的整数

, - * / 四个字符

日期(DayofMonth)

1~31的整数(需要考虑月的天数)

,- * ? / L W C 八个字符

月份(Month)

1~12的整数或者 JAN-DEC

,- * / 四个字符

星期(DayofWeek)

1~7的整数或者 SUN-SAT (1=SUN)

,- * ? / L C # 八个字符

年(可选,留空)(Year)

1970~2099

,- * / 四个字符

注意事项:

每一个域都使用数字,但还可以出现如下特殊字符,它们的含义是:

(1):表示匹配该域的任意值。假如在Minutes域使用, 即表示每分钟都会触发事件。

(2)?:只能用在DayofMonth和DayofWeek两个域。它也匹配域的任意值,但实际不会。因为DayofMonth和DayofWeek会相互影响。例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用如下写法:13 13 15 20 * ?, 其中最后一位只能用?,而不能使用*,如果使用*表示不管星期几都会触发,实际上并不是这样。

(3)-:表示范围。例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次

(4)/:表示起始时间开始触发,然后每隔固定时间触发一次。例如在Minutes域使用5/20,则意味着5分钟触发一次,而25,45等分别触发一次.

(5),:表示列出枚举值。例如:在Minutes域使用5,20,则意味着在5和20分每分钟触发一次。

(6)L:表示最后,只能出现在DayofWeek和DayofMonth域。如果在DayofWeek域使用5L,意味着在最后的一个星期四触发。

(7)W:表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。例如:在 DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份 。

(8)LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。

(9)#:用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。

三、常用表达式例子

(1)0 0 2 1 * ? * 表示在每月的1日的凌晨2点调整任务

(2)0 15 10 ? * MON-FRI 表示周一到周五每天上午10:15执行作业

(3)0 15 10 ? 6L 2002-2006 表示2002-2006年的每个月的最后一个星期五上午10:15执行作

(4)0 0 10,14,16 * * ? 每天上午10点,下午2点,4点

(5)0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时

(6)0 0 12 ? * WED 表示每个星期三中午12点

(7)0 0 12 * * ? 每天中午12点触发

(8)0 15 10 ? * * 每天上午10:15触发

(9)0 15 10 * * ? 每天上午10:15触发

(10)0 15 10 * * ? * 每天上午10:15触发

我也不会,不会去 http://cron.qqe2.com/网站去弄。

结语

灵活运用框架带来的开发便利,相对于使用原生的jdk的方法,如果有一个已经封装好,经过了别人多次的测试使用,又何必去浪费自己的时间去从头造轮子(甚至因为水平不足导致自己写的定时控制程序bug百出)。

再自我介绍一下吧。我叫润森,是一个的学习者,分享自己的所学所得。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-01-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小刘IT教程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 任务
  • 异步任务
  • 定时任务
  • Cron表达式
  • 结语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档