6

前言

这周总算是找到了状态,每天有时间就敲敲代码,感觉充实了好多,也正因为这种状态,才使得我顺利达到了上次汇报确立的目标,同时让我感慨的,就是目标的重要性,如果没有明确的目标,项目想要顺利往下进行着实有点难。
之前写的登录组件都是按照教程写的,所以打算提高一下,写点教程上没有的,虽说也得去各种博客上查吧,于是选择了自动推送功能的开发。

实践

博客上写了好多关于实现自动任务的方法,我就选择了比较简单的一种,毕竟有的复杂到还要下载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("执行定时任务" + dateString);
    }
}

@component (把pushTask实例化到spring容器中)
@scheduled (用来开启定时任务)
corn里面写的是执行的时间,这里把时间信息放到了配置文件中:

time:
  cron: 0 0 8 ? * *

corn有着自己的语法,像上面就是每天上午八点执行自动任务
cron表达式详解
在线Cron表达式生成器
@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

发现时间戳都是一样的,后来我看了一下主机时间,发现原来时间戳的时间是程序启动的时间,并不是随时获取的时间。
后来晚上开会的时候问了一下潘老师,才发现获取时间的代码位置出错了
修改如下:

//执行定时推送任务
@Component
public class pushTask {
    DingServiceImpl dingService = new DingServiceImpl();


    @Scheduled(cron = "${time.pushcron}")
    public void runTask(){
        LocalTime localTime = LocalTime.now();
        dingService.dingRequest("日志推送");
        System.out.println("执行定时任务" + localTime);
    }
    @Scheduled(cron="*/${time.interval} * * * * *")
    void run() {
        Instant timestamp = Instant.now();
        System.out.println("每五秒执行 " + timestamp);
    }
}

这样的话执行一次方法,就能获取一下时间,而并非像上面那样时间固定化。

2020-03-21 12:08:23.898  INFO 3899 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8114 (http) with context path ''
2020-03-21 12:08:23.899  INFO 3899 --- [           main] club.yunzhi.log.LogApplication           : Started LogApplication in 3.096 seconds (JVM running for 3.601)
每五秒执行 2020-03-21T04:08:25.001090Z
每五秒执行 2020-03-21T04:08:30.000510Z
每五秒执行 2020-03-21T04:08:35.000981Z
每五秒执行 2020-03-21T04:08:40.000595Z

总结

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

参考文档

@Scheduled注解各参数详解
spring boot 几种定时任务的实现方式
SpringBoot2.0集成Quartz


锦城
854 声望21 粉丝

好好生活