这里主要介绍使用Spring Task,Spring3.0以后自带的task,可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多。
首先在POM中导入依赖:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </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> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
创建任务执行类:
package com.example.demo.task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import com.example.demo.util.DateUtil; @Component public class ScheduledService { private final Logger log = LoggerFactory.getLogger(this.getClass()); @Scheduled(cron = "0/5 * * * * *") public void scheduled(){ log.info("使用cron执行:{}", DateUtil.getDateCurrent()); } // 它的间隔时间是根据上次的任务结束的时候开始计时的。 // 比如一个方法上设置了fixedDelay=5*1000,那么当该方法某一次执行结束后,开始计算时间,当时间达到5秒,就开始再次执行该方法。 // 加上注解@EnableAsync(类上)和@Async(方法上),加了注解以后,就开启了多线程模式, // 当到了下一次任务的执行时机时,如果上一次任务还没执行完,就会自动创建一个新的线程来执行它。 // 异步执行也可以理解为保证了任务以固定速度执行。 @Scheduled(fixedRate = 600*1000) public void scheduled1() { log.info("使用fixedRate执行:{}", DateUtil.getDateCurrent()); } // 它的间隔时间是根据上次任务开始的时候计时的。 // 比如当方法上设置了fiexdRate=5*1000,该执行该方法所花的时间是2秒,那么3秒后就会再次执行该方法。 @Scheduled(fixedDelay = 5000) public void scheduled2() { log.info("使用fixedDelay执行:{}", DateUtil.getDateCurrent()); } }
主要就是看@Scheduled注解,这三种方式的意思已经写在了注释上,更为细节的解释可以自行百度。
然后是启动类
package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableScheduling public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
这里增加了一个@EnableScheduling的注解在类上,否则不会启动Task。
我们看打印的日志
2021-03-22 11:14:34.653 INFO 7420 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2021-03-22 11:14:34.679 INFO 7420 --- [ scheduling-1] com.example.demo.task.ScheduledService : 使用fixedRate执行:2021-03-22 11:14:34 2021-03-22 11:14:34.679 INFO 7420 --- [ scheduling-1] com.example.demo.task.ScheduledService : 使用fixedDelay执行:2021-03-22 11:14:34 2021-03-22 11:14:34.682 INFO 7420 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 3.958 seconds (JVM running for 4.42) 2021-03-22 11:14:35.001 INFO 7420 --- [ scheduling-1] com.example.demo.task.ScheduledService : 使用cron执行:2021-03-22 11:14:35 2021-03-22 11:14:39.680 INFO 7420 --- [ scheduling-1] com.example.demo.task.ScheduledService : 使用fixedDelay执行:2021-03-22 11:14:39 2021-03-22 11:14:40.003 INFO 7420 --- [ scheduling-1] com.example.demo.task.ScheduledService : 使用cron执行:2021-03-22 11:14:40 2021-03-22 11:14:44.682 INFO 7420 --- [ scheduling-1] com.example.demo.task.ScheduledService : 使用fixedDelay执行:2021-03-22 11:14:44 2021-03-22 11:14:45.000 INFO 7420 --- [ scheduling-1] com.example.demo.task.ScheduledService : 使用cron执行:2021-03-22 11:14:45 2021-03-22 11:14:49.683 INFO 7420 --- [ scheduling-1] com.example.demo.task.ScheduledService : 使用fixedDelay执行:2021-03-22 11:14:49 2021-03-22 11:14:50.013 INFO 7420 --- [ scheduling-1] com.example.demo.task.ScheduledService : 使用cron执行:2021-03-22 11:14:50
我们看到三个方法使同一个线程中串行执行,如果只有一个定时任务,这样做肯定没问题,当定时任务增多,如果一个任务卡死,会导致其他任务也无法执行。
在传统的Spring项目中,我们可以在xml配置文件添加task的配置,而在SpringBoot项目中一般使用config配置类的方式添加配置,所以新建一个AsyncConfig类。
package com.example.demo.task; import java.util.concurrent.Executor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @Configuration @EnableAsync public class AsyncConfig { private int corePoolSize = 5; private int maxPoolSize = 10; private int queueCapacity = 10; @Bean public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(corePoolSize); executor.setMaxPoolSize(maxPoolSize); executor.setQueueCapacity(queueCapacity); executor.initialize(); return executor; } }
@Configuration:表明该类是一个配置类
@EnableAsync:开启异步事件的支持
然后在定时任务的类或者方法上添加@Async 。最后重启项目,每一个任务都是在不同的线程中。
2021-03-22 11:16:52.823 INFO 9708 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 3.888 seconds (JVM running for 4.346) 2021-03-22 11:16:52.832 INFO 9708 --- [ taskExecutor-1] com.example.demo.task.ScheduledService : 使用fixedRate执行:2021-03-22 11:16:52 2021-03-22 11:16:52.834 INFO 9708 --- [ taskExecutor-2] com.example.demo.task.ScheduledService : 使用fixedDelay执行:2021-03-22 11:16:52 2021-03-22 11:16:55.002 INFO 9708 --- [ taskExecutor-3] com.example.demo.task.ScheduledService : 使用cron执行:2021-03-22 11:16:55 2021-03-22 11:16:57.836 INFO 9708 --- [ taskExecutor-4] com.example.demo.task.ScheduledService : 使用fixedDelay执行:2021-03-22 11:16:57 2021-03-22 11:17:00.003 INFO 9708 --- [ taskExecutor-5] com.example.demo.task.ScheduledService : 使用cron执行:2021-03-22 11:17:00 2021-03-22 11:17:02.837 INFO 9708 --- [ taskExecutor-1] com.example.demo.task.ScheduledService : 使用fixedDelay执行:2021-03-22 11:17:02
结束
推荐您阅读更多有关于“ spring Task Timer springboot cron ”的文章
Java小强
未曾清贫难成人,不经打击老天真。
自古英雄出炼狱,从来富贵入凡尘。
发表评论: