schedule 通过数据库 动态新增任务

任务

@Component
public class DynamicPrintTask implements Runnable {
    public static Boolean isRun = false;
    @Autowired
    SpringScheduledCronRepository springScheduledCronRepository;

    @Override
    public void run() {
        if (isRun) return;
        isRun = true;
        System.out.println("-----=====定时任务"+ LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
        isRun = false;
    }
}

Utiles

public class BeanUtils {
    public static Field findField(Class<?> clazz, String name) {
        try {
            return clazz.getField(name);
        } catch (NoSuchFieldException ex) {
            return findDeclaredField(clazz, name);
        }
    }

    public static Field findDeclaredField(Class<?> clazz, String name) {
        try {
            return clazz.getDeclaredField(name);
        } catch (NoSuchFieldException ex) {
            if (clazz.getSuperclass() != null) {
                return findDeclaredField(clazz.getSuperclass(), name);
            }
            return null;
        }
    }

    public static Method findMethod(Class<?> clazz, String methodName, Class<?>... paramTypes) {
        try {
            return clazz.getMethod(methodName, paramTypes);
        } catch (NoSuchMethodException ex) {
            return findDeclaredMethod(clazz, methodName, paramTypes);
        }
    }

    public static Method findDeclaredMethod(Class<?> clazz, String methodName, Class<?>... paramTypes) {
        try {
            return clazz.getDeclaredMethod(methodName, paramTypes);
        } catch (NoSuchMethodException ex) {
            if (clazz.getSuperclass() != null) {
                return findDeclaredMethod(clazz.getSuperclass(), methodName, paramTypes);
            }
            return null;
        }
    }

    public static Object getProperty(Object obj, String name) throws NoSuchFieldException {
        Object value = null;
        Field field = findField(obj.getClass(), name);
        if (field == null) {
            throw new NoSuchFieldException("no such field [" + name + "]");
        }
        boolean accessible = field.isAccessible();
        field.setAccessible(true);
        try {
            value = field.get(obj);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        field.setAccessible(accessible);
        return value;
    }

    public static void setProperty(Object obj, String name, Object value) throws NoSuchFieldException {
        Field field = findField(obj.getClass(), name);
        if (field == null) {
            throw new NoSuchFieldException("no such field [" + name + "]");
        }
        boolean accessible = field.isAccessible();
        field.setAccessible(true);
        try {
            field.set(obj, value);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        field.setAccessible(accessible);
    }

    public static Map<String, Object> obj2Map(Object obj, Map<String, Object> map) {
        if (map == null) {
            map = new HashMap<String, Object>();
        }
        if (obj != null) {
            try {
                Class<?> clazz = obj.getClass();
                do {
                    Field[] fields = clazz.getDeclaredFields();
                    for (Field field : fields) {
                        int mod = field.getModifiers();
                        if (Modifier.isStatic(mod)) {
                            continue;
                        }
                        boolean accessible = field.isAccessible();
                        field.setAccessible(true);
                        map.put(field.getName(), field.get(obj));
                        field.setAccessible(accessible);
                    }
                    clazz = clazz.getSuperclass();
                } while (clazz != null);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return map;
    }

    /**
     * 获得父类集合,包含当前class
     *
     * @param clazz
     * @return
     */
    public static List<Class<?>> getSuperclassList(Class<?> clazz) {
        List<Class<?>> clazzes = new ArrayList<Class<?>>(3);
        clazzes.add(clazz);
        clazz = clazz.getSuperclass();
        while (clazz != null) {
            clazzes.add(clazz);
            clazz = clazz.getSuperclass();
        }
        return Collections.unmodifiableList(clazzes);
    }

SchedulingConfigurer

@Component
public class MyScheduleConfigurer implements SchedulingConfigurer {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private SpringScheduledCronRepository repository;

    private ScheduledTaskRegistrar taskRegistrar;

    @Autowired
    MyScheduleConfigurer scheConfigurer;

    //注入我们的定时任务类
    @Autowired
    DynamicPrintTask task;

    private Set<ScheduledFuture<?>> scheduledFutures = null;

    private Map<String, ScheduledFuture<?>> taskFutures = new ConcurrentHashMap<String, ScheduledFuture<?>>();

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {


        logger.info("configureTasks");

        List<SpringScheduledCron> springScheduledCrons = sortClearRules();

        this.taskRegistrar = taskRegistrar;
        this.taskRegistrar.setTaskScheduler(MyThreadPool.getScheduleTP(springScheduledCrons.size()+1));



        springScheduledCrons.forEach(springScheduledCron->{
            logger.info("springScheduledCrons = "+springScheduledCron.toString());
            scheConfigurer.addTriggerTask(springScheduledCron.getCron_id().toString(),new TriggerTask(task, triggerContext -> {
                //查询数据库  获得该类的cron表达式
                SpringScheduledCron springScheduledCronByCronKey = repository.findSpringScheduledCronById(springScheduledCron.getCron_id());
                String cronExpression = springScheduledCronByCronKey.getCron_expression();
                System.out.println(springScheduledCronByCronKey);
                // CronTrigger实现了Trigger
                return new CronTrigger(cronExpression).nextExecutionTime(triggerContext);
            }));
        });

    }

    /**
     * 添加任务
     *
     * @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);
    }



    private Set<ScheduledFuture<?>> getScheduledFutures() {
        if (scheduledFutures == null) {
            try {
                scheduledFutures = (Set<ScheduledFuture<?>>) BeanUtils.getProperty(taskRegistrar,  "scheduledTasks");
            } catch (NoSuchFieldException e) {
                throw new SchedulingException("not found scheduledFutures field.");
            }
        }
        return scheduledFutures;
    }


    /**
     * 取消任务
     *
     * @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;
    }
    /**
     * 初始化数据库数据
     * @return
     */
    private List<SpringScheduledCron> sortClearRules() {
        List<SpringScheduledCron> springScheduledCrons = repository.selectAll();
        springScheduledCrons.forEach(rule -> {
            logger.info("springScheduledCrons = "+springScheduledCrons);
        });
        return springScheduledCrons;
    }


}

实体类

@Table(name = "spring_scheduled_cron")
public class SpringScheduledCron {
    @Id
    @GeneratedValue(generator = "JDBC",strategy= GenerationType.AUTO)
    private Integer cron_id;
    private String cron_key;
    private String cron_expression;
    private String task_explain;
    private Integer status;

    public Integer getCron_id() {
        return cron_id;
    }

    public void setCron_id(Integer cron_id) {
        this.cron_id = cron_id;
    }

    public String getCron_key() {
        return cron_key;
    }

    public void setCron_key(String cron_key) {
        this.cron_key = cron_key;
    }

    public String getCron_expression() {
        return cron_expression;
    }

    public void setCron_expression(String cron_expression) {
        this.cron_expression = cron_expression;
    }

    public String getTask_explain() {
        return task_explain;
    }

    public void setTask_explain(String task_explain) {
        this.task_explain = task_explain;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    @Override
    public String toString() {
        return "SpringScheduledCron{" +
                "cron_id=" + cron_id +
                ", cron_key='" + cron_key + '\'' +
                ", cron_expression='" + cron_expression + '\'' +
                ", task_explain='" + task_explain + '\'' +
                ", status=" + status +
                '}';
    }
}

Dao

public interface SpringScheduledCronRepository extends BaseMapper<SpringScheduledCron> {

    //根据CronKey查找表达式
    @Select("select * from spring_scheduled_cron where cron_key = #{cronKey}")
    List<SpringScheduledCron> findSpringScheduledCronByCronKey(@Param("cronKey") String cronKey);

    //根据CronKey查找表达式
    @Select("select * from spring_scheduled_cron where cron_id = #{id}")
    SpringScheduledCron findSpringScheduledCronById(@Param("id") Integer id);
}

线程池

public class MyThreadPool {
    /**
     * 将queueSize=1,尽可能保持按任务提交顺序进行执行!
     *
     * @param maximumPoolSize
     *            线程池峰值线程个数
     * @return ThreadPoolExecutor
     */
    public static ThreadPoolExecutor getTP(int maximumPoolSize) {
        return (new ThreadPoolExecutor(maximumPoolSize / 10 + 1, maximumPoolSize, 2, TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(1), new CallerRunsPolicy()));

        // return (new ThreadPoolExecutor(maxPoolSize , maxPoolSize, 0,
        // TimeUnit.SECONDS,
        // new ArrayBlockingQueue<Runnable>(maxPoolSize + 5), new
        // ThreadPoolExecutor.CallerRunsPolicy()));
    }

    /**
     *
     * @param maximumPoolSize
     *            线程池峰值线程个数
     * @return ThreadPoolExecutor
     */
    public static ThreadPoolTaskScheduler getScheduleTP(int maximumPoolSize) {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(maximumPoolSize);
        taskScheduler.setThreadNamePrefix("TaskScheduler-ThreadPool-");
        // 线程池对拒绝任务(无线程可用)的处理策略,目前只支持AbortPolicy、CallerRunsPolicy;默认为后者
        taskScheduler.setRejectedExecutionHandler(new CallerRunsPolicy());
        // 调度器shutdown被调用时等待当前被调度的任务完成
        taskScheduler.setWaitForTasksToCompleteOnShutdown(true);
        // 等待时长
        taskScheduler.setAwaitTerminationSeconds(60);
        taskScheduler.initialize();
        return taskScheduler;
    }

    /**
     *
     * @param maximumPoolSize
     *            线程池峰值线程个数
     * @return ThreadPoolExecutor
     */
    public static ThreadPoolTaskExecutor getExecutorTP(int maximumPoolSize) {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(maximumPoolSize / 10 + 1);
        taskExecutor.setMaxPoolSize(maximumPoolSize);
        taskExecutor.setThreadNamePrefix("TaskExecutor-ThreadPool-");
        // 线程池对拒绝任务(无线程可用)的处理策略,目前只支持AbortPolicy、CallerRunsPolicy;默认为后者
        taskExecutor.setRejectedExecutionHandler(new CallerRunsPolicy());
        // 调度器shutdown被调用时等待当前被调度的任务完成
        taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        // 等待时长
        taskExecutor.setAwaitTerminationSeconds(60);
        taskExecutor.initialize();
        return taskExecutor;
    }


    /**
     * @param maximumPoolSize
     *            线程池峰值线程个数
     * @param queueSize
     *            线程池ArrayBlockingQueue大小
     * @return ThreadPoolExecutor
     */
    public static ThreadPoolExecutor getTP(int maximumPoolSize, int queueSize) {
        return (new ThreadPoolExecutor(maximumPoolSize / 10 + 1, maximumPoolSize, 2, TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(queueSize), new CallerRunsPolicy()));
    }

    /**
     * @param corePoolSize
     *            线程池初始线程个数
     * @param maximumPoolSize
     *            线程池峰值线程个数
     * @param queueSize
     *            线程池ArrayBlockingQueue大小
     * @return ThreadPoolExecutor
     */
    public static ThreadPoolExecutor getTP(int corePoolSize, int maximumPoolSize, int queueSize) {
        return (new ThreadPoolExecutor(corePoolSize, maximumPoolSize, 2, TimeUnit.SECONDS,
                new ArrayBlockingQueue<Runnable>(queueSize), new CallerRunsPolicy()));
    }

    /**
     * A handler for rejected tasks that runs the rejected task directly in the
     * calling thread of the {@code execute} method, unless the executor has
     * been shut down, in which case the task is discarded.
     */
    public static class CallerRunsPolicy implements RejectedExecutionHandler {
        /**
         * Creates a {@code CallerRunsPolicy}.
         */
        public CallerRunsPolicy() {
        }

        /**
         * Executes task r in the caller's thread, unless the executor has been
         * shut down, in which case the task is discarded.
         *
         * @param r
         *            the runnable task requested to be executed
         * @param e
         *            the executor attempting to execute this task
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            try {
                e.getQueue().put(r);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
            // if (!e.isShutdown()) {
            // r.run();
            // }
        }
    }

}



controller

 @RestController
@RequestMapping("/test")
public class TestController {
@GetMapping("/test")
public Result test(){

    myScheConfigurer.addTriggerTask("19",new TriggerTask((Runnable)task,triggerContext -> {
        return new CronTrigger("30 * * * * ?").nextExecutionTime(triggerContext);
    }));
// return    templateReportService.getSgxBEventProcessByTypeSum("2021-02-10","2021-03-29",2);
    return  null;
}
}

补充

  /**
     * 添加任务
     *
     * @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);
    }

这里添加任务是 不能直接使用 @Autowired 注入的 task 而必须使用 new 的形式

可以参考 https://blog.csdn.net/qq_38009686/article/details/121350600

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值