Springboot实现动态定时任务
该动态定时任务主配置类是 ScheduledConfig,代码如下;最近有幸要开发个动态定时任务,这里简单再梳理一下。到这里核心类已经走完,剩下的就是获取数据相关类。紧接着是这个类,用于控制任务的执行与否;最后就是要测试的接口。
·
最近有幸要开发个动态定时任务,这里简单再梳理一下。
Demo的整体结构如下:
pom.xml文件只需要导入一下依赖即可
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.6.0</version>
</dependency>
该动态定时任务主配置类是 ScheduledConfig,代码如下;
/**
* 定时任务主入口
*/
@Configuration
@EnableScheduling
public class ScheduledConfig implements SchedulingConfigurer {
@Autowired
private ApplicationContext context;
@Autowired
private DataService dataService;
private Logger logger = LoggerFactory.getLogger(ScheduledConfig.class);
//重点方法
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
for (DataCron dataCron : dataService.getAllData()) {
Class<?> clazz;
Object task = null;
try {
clazz = Class.forName(dataCron.getCronKey());
task = context.getBean(clazz);
} catch (Exception e) {
logger.error(e.getMessage());
}
if(task!=null){
//根据给定的Trigger添加要触发的 Runnable 任务。
taskRegistrar.addTriggerTask((Runnable) task, new Trigger() {
@Override
public Date nextExecutionTime(TriggerContext triggerContext) {
String cronExpression = dataService.findByCronKey(dataCron.getCronKey()).getCronExpression();
return new CronTrigger(cronExpression).nextExecutionTime(triggerContext);
}
});
}
}
}
@Bean
public Executor taskExecutor() {
return Executors.newScheduledThreadPool(5);
}
}
紧接着是这个类,用于控制任务的执行与否;
public interface ScheduledRunnable extends Runnable {
/**
* 实际要处理的任务
*/
void execute();
/**
* 控制定时任务启用或禁用的功能
*/
@Override
default void run() {
DataService dataService = SpringUtils.getBean(DataService.class);
DataCron scheduledCron = dataService.findByCronKey(this.getClass().getName());
if (!"1".equals(scheduledCron.getStatus())) {
// 任务是禁用状态
return;
}
execute();
}
}
上面代码使用到的SpringUtils工具类的代码如下:
@Component
public class SpringUtils implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringUtils.context = applicationContext;
}
public static <T> T getBean(Class<T> clz) {
return context.getBean(clz);
}
public static Object getBean(String name) {
return context.getBean(name);
}
public ApplicationContext getApplicationContext() {
return context;
}
}
真正实现任务调用的类是DynamicProcessTask,具体代码如下:
@Component
public class DynamicProcessTask implements ScheduledRunnable {
private Logger logger = LoggerFactory.getLogger(DynamicProcessTask.class);
@Autowired
private RestTemplate restTemplate;
private int i;
@Override
public void execute() {
logger.info("Thread Id:{} ---->>> execute times:{}", Thread.currentThread().getId(), ++i);
// 这里也可以继续抽取
restTemplate.postForEntity("http://localhost:8080/testCron",null, null);
}
}
到这里核心类已经走完,剩下的就是获取数据相关类
public interface DataService {
public List<DataCron> getAllData();
public DataCron findByCronKey(String str);
}
//DataService实现类
@Service
public class DataServiceImpl implements DataService {
//模拟数据 真实场景换成数据库数据
private static List<DataCron> list;
public DataServiceImpl(){
list = new ArrayList<>();
list.add(new DataCron("1","com.demo.task.DynamicProcessTask","0/5 * * * * ?","","1"));
list.add(new DataCron("2","com.demo.task.DynamicProcessTask2","0 0/2 * * * ?","","1"));
list.add(new DataCron("3","com.demo.task.DynamicProcessTask3","0 0/1 * * * ?","","1"));
}
@Override
public List<DataCron> getAllData() {
return list;
}
@Override
public DataCron findByCronKey(String str) {
for (int i = 0; i < list.size(); i++) {
DataCron dataCron = list.get(i);
if(dataCron.getCronKey().equals(str)){
return dataCron;
}
}
return null;
}
}
//实体类
public class DataCron {
private String cronId;
private String cronKey;
private String cronExpression;
private String taskExplain;
private String status;
//剩下方法自行补全
}
@Configuration
public class RestTemplateConfig {
private RestTemplate restTemplate;
@Bean
public RestTemplate getRestTemplate(RestTemplateBuilder restTemplateBuilder) {
this.restTemplate = new RestTemplate();
return restTemplate;
}
}
最后就是要测试的接口
@RestController
public class TestController {
private Logger logger = LoggerFactory.getLogger(TestController.class);
@PostMapping("/testCron")
public void testCron(){
logger.info("Thread id : {} ->>>>>>>>>>>>>>>> testCron",Thread.currentThread().getId());
}
}
测试效果如下:
更多推荐
已为社区贡献3条内容
所有评论(0)