转载

SpringBoot使用@Scheduled注解实现定时任务

前言

这周总算是找到了状态,每天有时间就敲敲代码,感觉充实了好多,也正因为这种状态,才使得我顺利达到了上次汇报确立的目标,同时让我感慨的,就是目标的重要性,如果没有明确的目标,项目想要顺利往下进行着实有点难。

之前写的登录组件都是按照教程写的,所以打算提高一下,写点教程上没有的,虽说也得去各种博客上查吧,于是选择了自动推送功能的开发。

实践

博客上写了好多关于实现自动任务的方法,我就选择了比较简单的一种,毕竟有的复杂到还要下载SQL文件,数据表多达十几个,暂时也不知道要不要记录推送任务执行情况,所以选择了Spring自带的@Scheduled注解方法。

首先就是声明依赖:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

之后使用MVN安装依赖即可

然后在启动类上添加@EnableScheduling注解

SpringBootApplication
@EnableAsync  // 启用异步
@ServletComponentScan
@EnableScheduling        // 启用定时任务
public class LogApplication {

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

}

之后就是新建java类,添加方法即可,在本项目中,新建timingtask文件夹,新建pushTask.java作为定时任务实现类文件

@Component
public class pushTask {
    Date currentTime = new Date();
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String dateString = formatter.format(currentTime);
    //
    @Scheduled(cron = "${time.cron}")
    public void runTask(){
        System.out.println("执行定时任务1" + dateString);
    }
}

@component (把pushTask实例化到spring容器中)

@scheduled (用来开启定时任务)

corn里面写的是执行的时间,这里把时间信息放到了配置文件中:

time:
  cron: 0 0 8 ? * *

corn有着自己的语法,像上面就是每天上午八点执行自动任务

@Scheduled注解下的方法便是自动执行的方法。

问题

下面以执行时间在12:57:50的方法为例

查看后台日志信息:

2020-03-20 12:57:24.120  INFO 22826 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8114 (http) with context path ''
2020-03-20 12:57:24.121  INFO 22826 --- [           main] club.yunzhi.log.LogApplication           : Started LogApplication in 2.635 seconds (JVM running for 3.022)
执行定时任务2020-03-20 12:57:23

方法执行的时间与主机上的时间相同,但是对于SpringBoot获取的时间戳来说,时间上还是有差距的,而且每次差距都不同。

解决

后来添加了一个按秒执行的方法run()

@Scheduled(cron="*/${time.interval} * * * * *")
    void run() {
        System.out.println("每五秒执行 " + dateString);
    }

配置文件

time:
  #特定时间
  cron: 50 05 13 ? * *
  #间隔秒数
  interval: 5

然后看一下日志信息:

2020-03-20 13:14:46.330  INFO 28915 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8114 (http) with context path ''
2020-03-20 13:14:46.332  INFO 28915 --- [           main] club.yunzhi.log.LogApplication           : Started LogApplication in 2.607 seconds (JVM running for 3.029)
每五秒执行 2020-03-20 13:14:45
每五秒执行 2020-03-20 13:14:45
每五秒执行 2020-03-20 13:14:45
每五秒执行 2020-03-20 13:14:45

发现时间戳都是一样的,后来我看了一下主机时间,发现原来时间戳的时间是程序启动的时间,并不是随时获取的时间。

总结

至于成不成功,还要经过许多测试才能下结论,之后打算结合宇轩开发的机器人测试一下定时任务,看情况再改进。

参考文档

@Scheduled注解各参数详解

spring boot 几种定时任务的实现方式

SpringBoot2.0集成Quartz
原文  https://segmentfault.com/a/1190000022083267
正文到此结束
Loading...