@Configuration
@EnableScheduling
public class CompleteScheduleConfig implements SchedulingConfigurer {
@Autowired
TaskService taskService;
private List<TaskBean> list;
private ScheduledTaskRegistrar mysCheduledTaskRegistrar;
@Autowired
SpringContextUtil springContextUtil;
private static AtomicBoolean run= new AtomicBoolean(false);
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
this.mysCheduledTaskRegistrar=scheduledTaskRegistrar;
scheduledTaskRegistrar.setScheduler(Executors.newScheduledThreadPool(40));
intTask();
}
public ScheduledFuture<?> addTask(Runnable runnable, Trigger trigger){
return mysCheduledTaskRegistrar.getScheduler().schedule(runnable,trigger);
}
/**
* 初始化定时任务
* @author 张志兴
* @date 2021/9/30 14:21
*/
public void intTask(){
TaskScheduler taskScheduler = mysCheduledTaskRegistrar.getScheduler();
ScheduledFuture<?> schedule = taskScheduler.schedule(
() -> {
list.forEach((taskBean -> {
if (stopTask(taskBean) && taskBean.getTaskRun()) {
ScheduledFuture<?> scheduledFuture = addTask(() -> new DyRunMethod(springContextUtil, taskBean.getTaskSpringBean(), taskBean.getTaskMethod()).executeMethod(taskBean), triggerContext -> {
return new CronTrigger(taskBean.getTaskCron()).nextExecutionTime(triggerContext);
});
//将定时任务加入到map缓存中
StaticFileds.taskFutures.put(taskBean.getTaskId(), new TaskFutureBean(scheduledFuture, taskBean.getTaskCron()));
}
}
)
);
}
,
triggerContext -> {
//定时3秒去数据库加载配置信息
list=taskService.getTask();
return new CronTrigger("0/3 * * * * ?").nextExecutionTime(triggerContext);
}
);
}
/**
* 检查运行中的任务的执行时间和新加载的运行时候是否一致,
* 如果一致,则不做任何操作
* 如果不一致,则取消运行中的任务,重新设置新的执行时间
* @author 张志兴
* @date 2021/9/30 14:19
* @param taskBean
* @return boolean
*/
public boolean stopTask(TaskBean taskBean){
if(StaticFileds.taskFutures.containsKey(taskBean.getTaskId())){
TaskFutureBean taskFutureBean=StaticFileds.taskFutures.get(taskBean.getTaskId());
if(!Objects.equals(taskBean.getTaskCron(),taskFutureBean.getExpression())){
taskFutureBean.getSchedule().cancel(false);
StaticFileds.taskFutures.remove(taskBean.getTaskId());
System.out.println("定时任务"+taskBean.getTaskId()+"执行被取消,将重新设置执行时间");
return true;
}else {
return false;
}
}
return true;
}
}
public class StaticFileds {
public StaticFileds() {
}
public StaticFileds getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
private static final StaticFileds INSTANCE = new StaticFileds();
}
public static Map<String, TaskFutureBean> taskFutures = new ConcurrentHashMap<String, TaskFutureBean>();
public static CopyOnWriteArrayList<String> runTaskIds=new CopyOnWriteArrayList<String>();
}
public interface TaskInterface {
void execute(Object object);
}
@TableName("task_table")
public class TaskBean {
public TaskBean(String taskId, String taskCron){
this.taskId=taskId;
this.taskCron=taskCron;
}
//任务Id
@TableField(value ="taskId",jdbcType = JdbcType.NVARCHAR)
private String taskId;
//执行时间
@TableField(value ="taskCron",jdbcType = JdbcType.NVARCHAR)
private String taskCron;
//任务调用SpringBean
@TableField(value ="taskSpringBean",jdbcType = JdbcType.NVARCHAR)
private String taskSpringBean;
//任务使用的方法
@TableField(value ="taskMethod",jdbcType = JdbcType.NVARCHAR)
private String taskMethod;
//任务是否被启用
@TableField(value = "taskRun",jdbcType = JdbcType.CHAR)
private boolean taskRun;
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
public String getTaskCron() {
return taskCron;
}
public void setTaskCron(String taskCron) {
this.taskCron = taskCron;
}
public String getTaskSpringBean() {
return taskSpringBean;
}
public void setTaskSpringBean(String taskSpringBean) {
this.taskSpringBean = taskSpringBean;
}
public String getTaskMethod() {
return taskMethod;
}
public void setTaskMethod(String taskMethod) {
this.taskMethod = taskMethod;
}
public boolean getTaskRun() {
return taskRun;
}
public void setTaskRun(boolean taskRun) {
this.taskRun = taskRun;
}
}
public class TaskFutureBean {
private ScheduledFuture<?> schedule;
private String expression;
public TaskFutureBean(ScheduledFuture<?> schedule, String expression){
this.schedule=schedule;
this.expression=expression;
}
public ScheduledFuture<?> getSchedule() {
return schedule;
}
public void setSchedule(ScheduledFuture<?> schedule) {
this.schedule = schedule;
}
public String getExpression() {
return expression;
}
public void setExpression(String expression) {
this.expression = expression;
}
}
@Service("taskService")
public class TaskServiceImpl implements TaskService, TaskInterface {
@Autowired
private TaskMapper taskMapper;
@Override
public List<TaskBean> getTask() {
List<TaskBean> list=taskMapper.selectByMap(new HashMap());
return list;
}
/**
* 定时任务自定义方法名
* @author 张志兴
* @date 2021/9/30 10:21
* @param taskBean
*/
@Override
public void customTaskMethod(TaskBean taskBean) {
StaticFileds.runTaskIds.add(taskBean.getTaskId());
//处理逻辑
System.out.println("方法名:customTaskMethod正在执行[任务ID"+taskBean.getTaskId()+"执行时间"+ LocalDateTime.now().toLocalTime()+"]");
}
/**
* 定时默认方法
* @author 张志兴
* @date 2021/9/30 10:19
* @param object
*/
@Override
public void execute(Object object) {
TaskBean taskBean= (TaskBean) object;
StaticFileds.runTaskIds.add(taskBean.getTaskId());
//处理逻辑
System.out.println("方法名:execute正在执行[任务ID"+taskBean.getTaskId()+"执行时间"+ LocalDateTime.now().toLocalTime()+"]");
}
}
/**
* @author 张志兴
* @date 2021年09月29日15:28
*/
public class DyRunMethod {
private SpringContextUtil springContextUtil;
private String bean;
private String method;
/**
*
* @author 张志兴
* @date 2021/9/29 15:50
* @param springContextUtil
* @param bean
* @param method
* @return null
*/
public DyRunMethod(SpringContextUtil springContextUtil,String bean,String method) {
this.springContextUtil = springContextUtil;
this.bean=bean;
this.method=method;
}
/**
*
* @author 张志兴
* @date 2021/9/29 15:50
* @param springContextUtil
* @param bean
* @return null
*/
public DyRunMethod(SpringContextUtil springContextUtil,String bean) {
this.springContextUtil = springContextUtil;
this.bean=bean;
this.method="execute";
}
/**
*
* @author 张志兴
* @date 2021/9/29 15:35
*/
public void executeMethod() {
Object ServiceImplType = springContextUtil.getBean(this.bean);
Method[] methods = ServiceImplType.getClass().getMethods();
for(Method m:methods){
if(m.getName().equals(this.method)){
try {
m.invoke(ServiceImplType);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
/**
*
* @author 张志兴
* @date 2021/9/29 15:36
* @param obj 参数
*/
public void executeMethod(Object obj) {
Object ServiceImplType = springContextUtil.getBean(this.bean);
Method[] methods = ServiceImplType.getClass().getMethods();
for(Method m:methods){
if(m.getName().equals(this.method)){
try {
m.invoke(ServiceImplType,obj);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
CREATE TABLE `task_table` (
`taskId` varchar(30) DEFAULT NULL,
`taskCron` varchar(30) DEFAULT NULL,
`taskSpringBean` varchar(200) DEFAULT NULL,
`taskMethod` varchar(200) DEFAULT 'execute',
`taskRun` char(2) DEFAULT '1'
)

执行一段时间后,手动到数据库中将任务1的执行间隔为13秒改为7秒。整个执行结果如下:
方法名:execute正在执行[任务ID1执行时间14:15:13.015]
方法名:customTaskMethod正在执行[任务ID2执行时间14:15:17.002]
方法名:execute正在执行[任务ID1执行时间14:15:26.003]
方法名:customTaskMethod正在执行[任务ID2执行时间14:15:34.014]
方法名:execute正在执行[任务ID1执行时间14:15:39.010]
方法名:customTaskMethod正在执行[任务ID2执行时间14:15:51.015]
方法名:execute正在执行[任务ID1执行时间14:15:52.010]
方法名:execute正在执行[任务ID1执行时间14:16:00.001]
方法名:customTaskMethod正在执行[任务ID2执行时间14:16:00.001]
方法名:execute正在执行[任务ID1执行时间14:16:13]
方法名:customTaskMethod正在执行[任务ID2执行时间14:16:17.015]
定时任务1执行被取消,将重新设置执行时间
###############任务1由间隔13秒执行一次自动变为了7秒执行一次
方法名:execute正在执行[任务ID1执行时间14:16:21.007]
方法名:execute正在执行[任务ID1执行时间14:16:28.001]
方法名:customTaskMethod正在执行[任务ID2执行时间14:16:34.012]
方法名:execute正在执行[任务ID1执行时间14:16:35.010]
方法名:execute正在执行[任务ID1执行时间14:16:42.003]
方法名:execute正在执行[任务ID1执行时间14:16:49.008]
方法名:customTaskMethod正在执行[任务ID2执行时间14:16:51.014]
方法名:execute正在执行[任务ID1执行时间14:16:56.007]
方法名:customTaskMethod正在执行[任务ID2执行时间14:17:00.010]
方法名:execute正在执行[任务ID1执行时间14:17:00.010]
方法名:execute正在执行[任务ID1执行时间14:17:07.010]
方法名:execute正在执行[任务ID1执行时间14:17:14.001]
方法名:customTaskMethod正在执行[任务ID2执行时间14:17:17.005]
方法名:execute正在执行[任务ID1执行时间14:17:21.005]
方法名:execute正在执行[任务ID1执行时间14:17:28.008]
方法名:customTaskMethod正在执行[任务ID2执行时间14:17:34.004]
方法名:execute正在执行[任务ID1执行时间14:17:35.012]
方法名:execute正在执行[任务ID1执行时间14:17:42.008]
方法名:execute正在执行[任务ID1执行时间14:17:49.003]
方法名:customTaskMethod正在执行[任务ID2执行时间14:17:51.010]
方法名:execute正在执行[任务ID1执行时间14:17:56.001]
方法名:execute正在执行[任务ID1执行时间14:18:00.011]
方法名:customTaskMethod正在执行[任务ID2执行时间14:18:00.011]
方法名:execute正在执行[任务ID1执行时间14:18:07.015]
方法名:execute正在执行[任务ID1执行时间14:18:14.011]
方法名:customTaskMethod正在执行[任务ID2执行时间14:18:17.014]
方法名:execute正在执行[任务ID1执行时间14:18:21.015]
方法名:execute正在执行[任务ID1执行时间14:18:28.012]
方法名:customTaskMethod正在执行[任务ID2执行时间14:18:34.010]
方法名:execute正在执行[任务ID1执行时间14:18:35.005]
方法名:execute正在执行[任务ID1执行时间14:18:42.014]
方法名:execute正在执行[任务ID1执行时间14:18:49.002]
方法名:customTaskMethod正在执行[任务ID2执行时间14:18:51.008]
方法名:execute正在执行[任务ID1执行时间14:18:56.001]
方法名:execute正在执行[任务ID1执行时间14:19:00.011]
方法名:customTaskMethod正在执行[任务ID2执行时间14:19:00.012]
方法名:execute正在执行[任务ID1执行时间14:19:07.001]
方法名:execute正在执行[任务ID1执行时间14:19:14.011]
方法名:customTaskMethod正在执行[任务ID2执行时间14:19:17.007]
方法名:execute正在执行[任务ID1执行时间14:19:21.012]
方法名:execute正在执行[任务ID1执行时间14:19:28.009]
方法名:customTaskMethod正在执行[任务ID2执行时间14:19:34.006]
方法名:execute正在执行[任务ID1执行时间14:19:35.015]
方法名:execute正在执行[任务ID1执行时间14:19:42.002]
方法名:execute正在执行[任务ID1执行时间14:19:49.007]
方法名:customTaskMethod正在执行[任务ID2执行时间14:19:51.012]
方法名:execute正在执行[任务ID1执行时间14:19:56.005]
方法名:customTaskMethod正在执行[任务ID2执行时间14:20:00.006]
方法名:execute正在执行[任务ID1执行时间14:20:00.006]
方法名:execute正在执行[任务ID1执行时间14:20:07.002]
方法名:execute正在执行[任务ID1执行时间14:20:14.011]
方法名:customTaskMethod正在执行[任务ID2执行时间14:20:17.001]
方法名:execute正在执行[任务ID1执行时间14:20:21.006]
方法名:execute正在执行[任务ID1执行时间14:20:28.002]
方法名:customTaskMethod正在执行[任务ID2执行时间14:20:34.002]
方法名:execute正在执行[任务ID1执行时间14:20:35.012]
方法名:execute正在执行[任务ID1执行时间14:20:42.003]
方法名:execute正在执行[任务ID1执行时间14:20:49.009]
方法名:customTaskMethod正在执行[任务ID2执行时间14:20:51.014]
方法名:execute正在执行[任务ID1执行时间14:20:56.001]
方法名:customTaskMethod正在执行[任务ID2执行时间14:21:00.006]
方法名:execute正在执行[任务ID1执行时间14:21:00.006]
方法名:execute正在执行[任务ID1执行时间14:21:07.011]
方法名:execute正在执行[任务ID1执行时间14:21:14.002]
方法名:customTaskMethod正在执行[任务ID2执行时间14:21:17.014]
方法名:execute正在执行[任务ID1执行时间14:21:21.012]
方法名:execute正在执行[任务ID1执行时间14:21:28.006]
方法名:customTaskMethod正在执行[任务ID2执行时间14:21:34.001]
方法名:execute正在执行[任务ID1执行时间14:21:35.014]
方法名:execute正在执行[任务ID1执行时间14:21:42.008]
方法名:execute正在执行[任务ID1执行时间14:21:49.008]
方法名:customTaskMethod正在执行[任务ID2执行时间14:21:51.002]
方法名:execute正在执行[任务ID1执行时间14:21:56.014]
方法名:execute正在执行[任务ID1执行时间14:22:00.001]
方法名:customTaskMethod正在执行[任务ID2执行时间14:22:00.001]
方法名:execute正在执行[任务ID1执行时间14:22:07.012]
方法名:execute正在执行[任务ID1执行时间14:22:14.010]
方法名:customTaskMethod正在执行[任务ID2执行时间14:22:17.007]
方法名:execute正在执行[任务ID1执行时间14:22:21.011]
方法名:execute正在执行[任务ID1执行时间14:22:28.008]
方法名:customTaskMethod正在执行[任务ID2执行时间14:22:34.004]
方法名:execute正在执行[任务ID1执行时间14:22:35.001]
方法名:execute正在执行[任务ID1执行时间14:22:42.012]
方法名:execute正在执行[任务ID1执行时间14:22:49.012]
方法名:customTaskMethod正在执行[任务ID2执行时间14:22:51.001]
方法名:execute正在执行[任务ID1执行时间14:22:56.009]
方法名:customTaskMethod正在执行[任务ID2执行时间14:23:00.009]
方法名:execute正在执行[任务ID1执行时间14:23:00.010]
方法名:execute正在执行[任务ID1执行时间14:23:07.010]
方法名:execute正在执行[任务ID1执行时间14:23:14.001]
方法名:customTaskMethod正在执行[任务ID2执行时间14:23:17.008]
方法名:execute正在执行[任务ID1执行时间14:23:21.010]
方法名:execute正在执行[任务ID1执行时间14:23:28.014]
方法名:customTaskMethod正在执行[任务ID2执行时间14:23:34.007]
方法名:execute正在执行[任务ID1执行时间14:23:35.002]
方法名:execute正在执行[任务ID1执行时间14:23:42.005]
方法名:execute正在执行[任务ID1执行时间14:23:49.015]
方法名:customTaskMethod正在执行[任务ID2执行时间14:23:51.004]
方法名:execute正在执行[任务ID1执行时间14:23:56.011]
方法名:execute正在执行[任务ID1执行时间14:24:00.001]
方法名:customTaskMethod正在执行[任务ID2执行时间14:24:00.001]
方法名:execute正在执行[任务ID1执行时间14:24:07.008]
到此为止,功能已经基本实现。
该代码示例展示了如何使用Spring Boot实现动态定时任务管理。通过监听数据库中任务配置的变化,自动调整任务的执行间隔。当任务配置更新时,会取消原有任务并重新设置执行时间,确保任务按照最新配置执行。
1万+

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



