工作中有时候需要做很多定时任务处理,springboot自带的Scheduling很不错的选择,然而我们一般使用可能是写死的一个定时任务
@Component("jobs")
public class Jobs {
protected static final Logger logger = LoggerFactory.getLogger(Jobs.class);
@Scheduled(cron="0 */2 * * * ? ")
public void test(){
logger.debug("run test one minitue per time");
}
}
然后在主启动的时候 加EnableScheduling这注解就可以定时调度了,不过这个是写死的,有时候需要灵活修改时间,就必须要重启了,
@SpringBootApplication
@EnableAutoConfiguration
@EnableScheduling
@ComponentScan(basePackages ="com.asiainfo.selenuim")
public class Main {
protected static final Logger logger = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
logger.debug("spring启动成功");
// test();
}
最近有个项目恰好用到定时调度动态修改的,于是网上找了一番,抄袭的原作者的代码,稍加改动了,因为原作者的我启动报错了,注释掉部分是我改动的地方原作者的网页地址没找到了。
运行TestJob就可以观察到效果了,一个线程启动定时任务,另一个线程过30s后修改掉定时任务的时间
package com.asiainfo.crm.dbcloud.jobs;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import org.springframework.scheduling.SchedulingException;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.config.TriggerTask;
import org.springframework.stereotype.Component;
import com.asiainfo.crm.dbcloud.utils.BeanUtils;
/**
* 默认任务调度配置
*
* @author jianggujin
*
*/
@EnableScheduling
@Component
public class DefaultSchedulingConfigurer implements SchedulingConfigurer {
private final String FIELD_SCHEDULED_FUTURES = "scheduledFutures";
private ScheduledTaskRegistrar taskRegistrar;
private Set<ScheduledFuture<?>> scheduledFutures = null;
private Map<String, ScheduledFuture<?>> taskFutures = new ConcurrentHashMap<String, ScheduledFuture<?>>();
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
this.taskRegistrar = taskRegistrar;
}
@SuppressWarnings("unchecked")
private Set<ScheduledFuture<?>> getScheduledFutures() {
// if (scheduledFutures == null) {
// try {
// scheduledFutures = (Set<ScheduledFuture<?>>) BeanUtils.getProperty(taskRegistrar,
// FIELD_SCHEDULED_FUTURES);
// } catch (NoSuchFieldException e) {
// e.printStackTrace();
// throw new SchedulingException("not found scheduledFutures field.");
// }
// }
// return scheduledFutures;
return new HashSet<ScheduledFuture<?>>();
}
/**
* 添加任务
*
* @param taskId
* @param triggerTask
*/
public void addTriggerTask(String taskId, TriggerTask triggerTask) {
if (taskFutures.containsKey(taskId)) {
throw new SchedulingException("the taskId[" + taskId + "] was added.");
}
TaskScheduler scheduler = taskRegistrar.getScheduler();
ScheduledFuture<?> future = scheduler.schedule(triggerTask.getRunnable(), triggerTask.getTrigger());
getScheduledFutures().add(future);
taskFutures.put(taskId, future);
}
/**
* 取消任务
*
* @param taskId
*/
public void cancelTriggerTask(String taskId) {
ScheduledFuture<?> future = taskFutures.get(taskId);
if (future != null) {
future.cancel(true);
}
taskFutures.remove(taskId);
getScheduledFutures().remove(future);
}
/**
* 重置任务
*
* @param taskId
* @param triggerTask
*/
public void resetTriggerTask(String taskId, TriggerTask triggerTask) {
cancelTriggerTask(taskId);
addTriggerTask(taskId, triggerTask);
}
/**
* 任务编号
*
* @return
*/
public Set<String> taskIds() {
return taskFutures.keySet();
}
/**
* 是否存在任务
*
* @param taskId
* @return
*/
public boolean hasTask(String taskId) {
return this.taskFutures.containsKey(taskId);
}
/**
* 任务调度是否已经初始化完成
*
* @return
*/
public boolean inited() {
return this.taskRegistrar != null && this.taskRegistrar.getScheduler() != null;
}
}
package com.asiainfo.crm.dbcloud.jdbc;
import java.util.Calendar;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.config.TriggerTask;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import com.asiainfo.crm.dbcloud.jobs.DefaultSchedulingConfigurer;
@Component
public class TestJob implements InitializingBean {
@Autowired
private DefaultSchedulingConfigurer defaultSchedulingConfigurer;
public void afterPropertiesSet() throws Exception {
new Thread() {
public void run() {
try {
// 等待任务调度初始化完成
while (!defaultSchedulingConfigurer.inited()) {
Thread.sleep(100);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务调度初始化完成,添加任务");
defaultSchedulingConfigurer.addTriggerTask("task", new TriggerTask(new Runnable() {
@Override
public void run() {
System.out.println("run job..." + Calendar.getInstance().get(Calendar.SECOND));
}
}, new CronTrigger("0/5 * * * * ? ")));
};
}.start();
new Thread() {
public void run() {
try {
Thread.sleep(30000);
} catch (Exception e) {
}
System.out.println("重置任务............");
defaultSchedulingConfigurer.resetTriggerTask("task", new TriggerTask(new Runnable() {
@Override
public void run() {
System.out.println("run job..." + Calendar.getInstance().get(Calendar.SECOND));
}
}, new CronTrigger("0/10 * * * * ? ")));
};
}.start();
}
}

本文介绍如何在SpringBoot中实现动态修改定时任务的配置,避免任务写死并需要重启应用的情况。通过自定义`DefaultSchedulingConfigurer`实现任务的添加、取消和重置,结合`TriggerTask`和`CronTrigger`,可以在应用运行时灵活调整任务执行时间。

1019

被折叠的 条评论
为什么被折叠?



