前言
这周总算是找到了状态,每天有时间就敲敲代码,感觉充实了好多,也正因为这种状态,才使得我顺利达到了上次汇报确立的目标,同时让我感慨的,就是目标的重要性,如果没有明确的目标,项目想要顺利往下进行着实有点难。
之前写的登录组件都是按照教程写的,所以打算提高一下,写点教程上没有的,虽说也得去各种博客上查吧,于是选择了自动推送功能的开发。
实践
博客上写了好多关于实现自动任务的方法,我就选择了比较简单的一种,毕竟有的复杂到还要下载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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。