springboot执行动态定时任务(TaskScheduler)

背景

在公司做项目的时候碰到一个需求,要求为可以自定义配置动态任务的开始时间,由于一开始只想到使用@Schedule来进行,但显然不满足需求,为此,询问同事后得知有一种可以自定义定时任务的用法,遂记录一波

定时任务的管理类

@Component
public class ComfirmManager{
	@Autowired
    private TaskScheduler threadPoolTaskScheduler;
    private static Map<String,ScheduledFuture<?>> scheduledFutureMap = new HashMap<>(16);

    /**
     * 增加定时任务
     */
    public void addConfirm() {
    	StringBuilder cronOrderL = new StringBuilder();
        StringBuilder cronOrderD = new StringBuilder();
        
        //这个步骤是为了取数据库存放的定时任务的启动时间,格式为时分秒
        Dict orderLconfirmedTime = dictService.getOne(new LambdaQueryWrapper<Dict>().eq(Dict::getCode, "ORDER_LCONFIRMED_TIME"));
        Dict orderDconfirmedTime = dictService.getOne(new LambdaQueryWrapper<Dict>().eq(Dict::getCode, "ORDER_DCONFIRMED_TIME"));
        String[] splitOrderD = orderDconfirmedTime.getVal().split(":");
        String[] splitOrderL = orderLconfirmedTime.getVal().split(":");

        //拼接cron表达式并设置定时任务到系统当中
        cronOrderL.append(splitOrderL[2]).append(" ").append(splitOrderL[1]).append(" ").append(splitOrderL[0]).append(" * * ? ");
        cronOrderD.append(splitOrderD[2]).append(" ").append(splitOrderD[1]).append(" ").append(splitOrderD[0]).append(" * * ? ");
        ScheduledFuture<?> scheduleOrderL = threadPoolTaskScheduler.schedule(new OrderLunchRunnable(), triggerContext -> new CronTrigger(cronOrderL.toString()).nextExecutionTime(triggerContext));
        ScheduledFuture<?> scheduleOrderD = threadPoolTaskScheduler.schedule(new OrderDinnerRunnable(), triggerContext -> new CronTrigger(cronOrderD.toString()).nextExecutionTime(triggerContext));

        scheduledFutureMap.put("scheduleOrderL",scheduleOrderL);
        scheduledFutureMap.put("scheduleOrderD",scheduleOrderD);
    }

    /**
     * 删除定时任务
     */
    public void deleteConfirm() {

        for (Map.Entry<String, ScheduledFuture<?>> entry : scheduledFutureMap.entrySet()) {
            entry.getValue().cancel(true);
        }
    }

}

两个定时任务实现代码

public class OrderLunchRunnable implements Runnable{

	private DictMapper dictMapper = ManageSpringBeans.getBean(DictMapper.class);
    private OrderMapper orderMapper = ManageSpringBeans.getBean(OrderMapper.class);

	@Override
    public void run() {
		System.out.println("执行相关定时任务");
	}
}

public class OrderDinnerRunnable implements Runnable{

	private DictMapper dictMapper = ManageSpringBeans.getBean(DictMapper.class);
    private OrderMapper orderMapper = ManageSpringBeans.getBean(OrderMapper.class);

	@Override
    public void run() {
		System.out.println("执行相关定时任务");
	}
}

注意点:因为类继承了Runnable,是没有办法直接使用@Autowired去获取相关的bean,所以这个时候需要写一个ManageSpringBeans工具类来替代注解去获得相关的bean

@Component
public class ManageSpringBeans implements ApplicationContextAware {

    private static ApplicationContext context;

    public static <T> T getBean(final Class<T> requiredType) {
        return context.getBean(requiredType);
    }

    public static <T> T getBean(final String beanName) {
        @SuppressWarnings("unchecked")
        final T bean = (T) context.getBean(beanName);
        return bean;
    }

    public static <T> Map<String, T> getBeans(final Class<T> requiredType) {
        return context.getBeansOfType(requiredType);
    }

    public static Map<String, Object> getBeansWithAnnotation(final Class<? extends Annotation> annotationType) {
        return context.getBeansWithAnnotation(annotationType);
    }

    @Override
    public void setApplicationContext(final ApplicationContext applicationContext) {
        context = applicationContext;
    }
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot提供了一个方便的方式来动态添加定时任务。您可以使用Spring的@Scheduled注释来定义定时任务,并使用Spring的TaskScheduler接口来动态添加和删除任务。 首先,您需要定义一个定时任务类,该类应该包含一个方法,该方法将在指定的时间间隔内运行。您可以使用@Scheduled注释来定义方法的运行时间。例如,以下代码定义了一个每分钟运行一次的定时任务: ``` @Component public class MyTask { @Scheduled(cron = "0 * * * * ?") public void run() { // do something } } ``` 接下来,您需要使用TaskScheduler接口来动态添加和删除任务。您可以使用ScheduledFuture接口来跟踪任务的状态,并使用TaskScheduler.schedule方法来添加任务。例如,以下代码动态添加了一个每5分钟运行一次的定时任务: ``` @Component public class TaskScheduler { @Autowired private ThreadPoolTaskScheduler threadPoolTaskScheduler; private ScheduledFuture<?> scheduledFuture; public void addTask() { scheduledFuture = threadPoolTaskScheduler.schedule(new MyTask(), new CronTrigger("0 */5 * * * *")); } public void removeTask() { if (scheduledFuture != null) { scheduledFuture.cancel(true); } } } ``` 在上面的代码中,TaskScheduler类使用@Autowired注释注入了一个ThreadPoolTaskScheduler实例,该实例是Spring Boot提供的一个线程池。然后,TaskScheduler类定义了一个addTask方法,该方法使用TaskScheduler.schedule方法添加了一个每5分钟运行一次的定时任务TaskScheduler类还定义了一个removeTask方法,该方法使用ScheduledFuture.cancel方法取消了任务的执行。 最后,您需要在Spring Boot应用程序的配置文件中配置ThreadPoolTaskScheduler。例如,以下代码配置了一个最大线程数为10的线程池: ``` @Configuration @EnableScheduling public class AppConfig { @Bean public ThreadPoolTaskScheduler threadPoolTaskScheduler() { ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); threadPoolTaskScheduler.setPoolSize(10); threadPoolTaskScheduler.setThreadNamePrefix("ThreadPoolTaskScheduler"); return threadPoolTaskScheduler; } } ``` 在上面的代码中,AppConfig类使用@Bean注释定义了一个ThreadPoolTaskScheduler实例,并使用setPoolSize方法设置了最大线程数为10。然后,AppConfig类使用@EnableScheduling注释启用了Spring的定时任务功能。 现在,您可以在Spring Boot应用程序中动态添加和删除定时任务了。只需调用TaskScheduler类的addTask和removeTask方法即可。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值