SpringBoot使用ScheduledFuture实现一个动态的定时任务

最近的工作业务中,涉及到了一个动态的定时任务功能,用户在页面中生成cron表达式,后台进行一个动态定时任务的启停功能

1.实现SchedulingConfigurer接口,在重写的方法中为ScheduledTaskRegistrar创建一个定时任务,并把任务注册器拿到,后面设置cron要用到,因为ScheduledFuture初始化会调用一次afterPropertiesSet方法创建一个单线程的线程池,所以我们首次不需要运行,后执行执行该方法是覆盖之前的任务。这样就达到了动态更新定时任务的效果。缺点可能不适合多个定时任务场景,没试。。可自测

 

 

   private ScheduledTaskRegistrar taskRegistrar=null;

 

  /**
     * 动态更新cron
     * @param
     */
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        log.info("cron的值为:{}",cron);
       if ( taskRegistrar.getScheduledTasks().size()>0){
           taskRegistrar.afterPropertiesSet();
       }
        this.taskRegistrar=taskRegistrar;
        taskRegistrar.addTriggerTask(this::prepareScan, triggerContext -> {
            CronTrigger trigger = new CronTrigger(cron);
            return trigger.nextExecutionTime(triggerContext);
        });
    }

触发方法:调用重写的该方法传入注册器和cron

    /**
     * 更改定时cron
     */
    public void setCronTime(String cron) {
        // 分页查询
        this.setCron(cron);
        this.configureTasks(taskRegistrar);
    }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面是一个简单的 springboot+vue 实现动态定时任务的示例代码: 后端代码: 1. 创建一个定时任务实体类 TaskEntity.java ,用于存储任务信息: ```java @Entity @Table(name = "task") public class TaskEntity { @Id @GeneratedValue(strategy= GenerationType.IDENTITY) private Long id; private String cron; private String className; private String methodName; private Integer status; private String remark; // 省略 getter 和 setter 方法 } ``` 2. 创建一个定时任务服务类 TaskService.java ,用于操作定时任务: ```java @Service public class TaskService { @Autowired private TaskRepository taskRepository; @Autowired private TaskExecutor taskExecutor; /** * 添加定时任务 * @param taskEntity */ public void addTask(TaskEntity taskEntity) { taskEntity.setStatus(0); taskRepository.save(taskEntity); // 启动定时任务 taskExecutor.addTask(taskEntity); } /** * 删除定时任务 * @param id */ public void deleteTask(Long id) { TaskEntity taskEntity = taskRepository.findById(id).get(); taskRepository.delete(taskEntity); // 停止定时任务 taskExecutor.removeTask(taskEntity); } /** * 更新定时任务 * @param taskEntity */ public void updateTask(TaskEntity taskEntity) { taskRepository.save(taskEntity); // 重新启动定时任务 taskExecutor.removeTask(taskEntity); taskExecutor.addTask(taskEntity); } /** * 获取所有定时任务 * @return */ public List<TaskEntity> getAllTasks() { return taskRepository.findAll(); } } ``` 3. 创建一个定时任务执行器 TaskExecutor.java ,用于执行定时任务: ```java @Component public class TaskExecutor { private ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(10); /** * 添加定时任务 * @param taskEntity */ public void addTask(TaskEntity taskEntity) { String cron = taskEntity.getCron(); // 创建定时任务 Runnable task = () -> { try { // 反射调用方法 Class<?> clazz = Class.forName(taskEntity.getClassName()); Method method = clazz.getMethod(taskEntity.getMethodName()); Object obj = clazz.newInstance(); method.invoke(obj); } catch (Exception e) { e.printStackTrace(); } }; // 添加定时任务 ScheduledFuture<?> future = executorService.schedule(task, new CronTrigger(cron)); taskEntity.setScheduledFuture(future); } /** * 删除定时任务 * @param taskEntity */ public void removeTask(TaskEntity taskEntity) { ScheduledFuture<?> future = taskEntity.getScheduledFuture(); if (future != null) { future.cancel(true); } } } ``` 4. 创建一个定时任务仓库 TaskRepository.java ,用于操作数据库: ```java @Repository public interface TaskRepository extends JpaRepository<TaskEntity, Long> { } ``` 5. 创建一个定时任务控制器 TaskController.java ,用于接收前端请求: ```java @RestController @RequestMapping("/task") public class TaskController { @Autowired private TaskService taskService; /** * 添加定时任务 * @param taskEntity * @return */ @PostMapping("/add") public String addTask(@RequestBody TaskEntity taskEntity) { taskService.addTask(taskEntity); return "success"; } /** * 删除定时任务 * @param id * @return */ @PostMapping("/delete") public String deleteTask(@RequestParam Long id) { taskService.deleteTask(id); return "success"; } /** * 更新定时任务 * @param taskEntity * @return */ @PostMapping("/update") public String updateTask(@RequestBody TaskEntity taskEntity) { taskService.updateTask(taskEntity); return "success"; } /** * 获取所有定时任务 * @return */ @GetMapping("/getAll") public List<TaskEntity> getAllTasks() { return taskService.getAllTasks(); } } ``` 前端代码: 1. 创建一个定时任务表格 TaskTable.vue ,用于展示和操作定时任务: ```html <template> <div> <el-table :data="tasks" style="width: 100%"> <el-table-column prop="id" label="ID"></el-table-column> <el-table-column prop="cron" label="Cron 表达式"></el-table-column> <el-table-column prop="className" label="类名"></el-table-column> <el-table-column prop="methodName" label="方法名"></el-table-column> <el-table-column prop="status" label="状态" :formatter="formatStatus"></el-table-column> <el-table-column prop="remark" label="备注"></el-table-column> <el-table-column label="操作"> <template slot-scope="scope"> <el-button type="text" @click="editTask(scope.row)">编辑</el-button> <el-button type="text" @click="deleteTask(scope.row)">删除</el-button> </template> </el-table-column> </el-table> <el-dialog :visible.sync="dialogVisible"> <el-form :model="task" label-width="80px"> <el-form-item label="Cron 表达式"> <el-input v-model="task.cron"></el-input> </el-form-item> <el-form-item label="类名"> <el-input v-model="task.className"></el-input> </el-form-item> <el-form-item label="方法名"> <el-input v-model="task.methodName"></el-input> </el-form-item> <el-form-item label="备注"> <el-input v-model="task.remark"></el-input> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="dialogVisible = false">取 消</el-button> <el-button type="primary" @click="saveTask">确 定</el-button> </div> </el-dialog> </div> </template> <script> export default { data() { return { tasks: [], task: {}, dialogVisible: false }; }, created() { this.getAllTasks(); }, methods: { // 获取所有定时任务 getAllTasks() { this.$axios.get("/task/getAll").then(response => { this.tasks = response.data; }); }, // 格式化状态 formatStatus(row) { return row.status === 0 ? "停止" : "运行"; }, // 编辑定时任务 editTask(row) { this.task = Object.assign({}, row); this.dialogVisible = true; }, // 删除定时任务 deleteTask(row) { this.$axios.post("/task/delete?id=" + row.id).then(response => { if (response.data === "success") { this.getAllTasks(); } }); }, // 保存定时任务 saveTask() { if (!this.task.cron || !this.task.className || !this.task.methodName) { this.$message.error("请填写完整信息!"); return; } const url = this.task.id ? "/task/update" : "/task/add"; this.$axios.post(url, this.task).then(response => { if (response.data === "success") { this.dialogVisible = false; this.getAllTasks(); } }); } } }; </script> ``` 2. 创建一个定时任务管理页面 TaskManager.vue ,用于展示定时任务表格和添加定时任务的按钮: ```html <template> <div> <el-button type="primary" @click="dialogVisible = true">添加定时任务</el-button> <task-table></task-table> </div> </template> <script> import TaskTable from "@/components/TaskTable.vue"; export default { components: { TaskTable }, data() { return { dialogVisible: false }; } }; </script> ``` 以上代码仅供参考,具体实现还需要根据业务需求进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值