在实际项目开发中,定时任务是经常使用到的,例如周期性地完成某些任务。在 SpringBoot 项目中,我们通常使用的是 @Scheduled 注解来完成设置定时任务规则,但是有时候我们需要对周期性的时间设置做一些改变,那么这个时候使用此注解就不太方便了,原因在于这个注解中配置的 cron 表达式必须是常量,那么当我们修改定时参数的时候,就需要重新编译打包,重新部署。实际使用起来不是很方便。
为了实际项目不需要重新编译,我们需要动态配置 cron 表达式。一种可能的实现方式,是实现 SchedulingConfigurer 接口,步骤如下。
一、添加 @EnableScheduling 注解
可以在 SpringBoot 的启动类上添加开启定时任务注解,也可以在具体的定时任务类上添加该注解,以下两种方法都是可行的。
1.1 启动类加注解
package *****;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@SpringBootApplication
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
@EnableTransactionManagement
@EnableScheduling
public class TestServerApplication {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(TestServerApplication .class);
springApplication.run(args);
}
}
1.2 定时任务类加注解
本文代码示例使用的此种方法,见下方源码。
二、定义具体任务,实现 SchedulingConfigurer 接口。
package *****.task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.stereotype.Component;
@Component
@EnableScheduling
public class TestTask implements SchedulingConfigurer {
private static Logger logger = LoggerFactory.getLogger(TestTask.class);
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
// TODO: 2019/4/19 定时任务表达式,实际项目可以从配置文件、数据库等中获取
String cron = "0 0 8,23 * * *";
taskRegistrar.addCronTask(new Runnable() {
@Override
public void run() {
// TODO: 2019/4/19 具体要做的任务,例如:输出
System.out.println("===== test cron ok =====");
}
}, cron);
}
}
定时任务还有其他实现方法,本文只写一种。