第一步是在应用启动类上添加@EnableScheduling
注解来允许当前应用开启定时任务。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* @author mhlevel
* @date 2020-08-20 11:44
*/
@SpringBootApplication
@EnableScheduling
public class springbootApplication {
public static void main(String[] args) {
SpringApplication.run(springbootApplication.class, args);
}
}
第二步是创建一个定时任务的类,它里面可能会包含很多个定时任务(一个任务就是对应到类中的一个方法),注意,这个定时任务类需要用@Component
注解标注,以便Spring 容器能扫描到这个类
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class OrderJob {
@Scheduled(cron = "0/3 * * * * ? ")
public void autoCloseOrder(){
System.out.println("执行定时任务,当前时间为:"+ new Date());
}
}
其中cron的值,可以在在线Cron表达式生成器此网页中设置自己想要间隔的时间,自动生成对应的cron表达式。比如我这边设置的是每隔3秒,执行一次。
测试
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* @author mhlevel
* @date 2020-08-20 21:19
*/
@Slf4j
@Component
public class BootSchedule {
private final DateTimeFormatter fmt = DateTimeFormatter.ofPattern(
"HH:mm:ss"
);
// 上次任务开始后隔三秒开启下一次任务
@Scheduled(fixedRate = 3000)
public void schedule01(){
log.info("schedule01 -> {}", LocalDateTime.now().format(fmt));
}
// 上次任务执行完毕的时间点之后3s再执行
@Scheduled(fixedDelay = 3000)
public void schedule02(){
log.info("schedule02 -> {}", LocalDateTime.now().format(fmt));
}
// 第一次延后2s 执行,之后每3s 执行一次
@Scheduled(initialDelay = 1000, fixedRate = 3000)
public void schedule03(){
log.info("schedule03 -> {}", LocalDateTime.now().format(fmt));
}
// 每3s 执行一次
@Scheduled(cron = "0/3 * * * * ?")
public void schedule04(){
log.info("shedule04 -> {}", LocalDateTime.now().format(fmt));
}
}
corn表达式解释
只在项目第一次启动的时候启动
使用配置类
- ApplicationContext事件机制是观察者设计模式的实现,通过ApplicationEvent类和ApplicationListener接口,可以实现ApplicationContext事件处理,我们这里就只用ApplicationListener接口就行。
- 如果容器中存在ApplicationListener的Bean,当ApplicationContext调用publishEvent方法时,对应的Bean会被触发。
用到了Spring的内置事件ContextRefreshedEvent,当ApplicationContext被初始化或刷新时,会触发ContextRefreshedEvent事件
@Service
//项目启动自动执行方法的配置类
public class SearchReceiveConfig implements ApplicationListener<ContextRefreshedEvent> {
//注入
@Autowired
private TestService testService;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
//保证只执行一次
if (event.getApplicationContext().getParent()==null){
//需要执行的方法
this.testService.getTest();
}
}
}
Service层
@Service
public class TestService {
public void getTest(){
System.out.println("测试");
}
}