这里主要介绍使用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小强
未曾清贫难成人,不经打击老天真。
自古英雄出炼狱,从来富贵入凡尘。
发表评论: