Spring boot 动态创建定时任务

深碍√TFBOYSˉ_ 2023-10-04 16:56 132阅读 0赞
  1. 首先创建定时任务实体

    /**

    • @author liangxuelong
    • @version 1.0
    • @description: 定时任务配置
    • @date 2021/8/25 9:45
      */
      @Data
      public class Scheduled {
  1. private String id;
  2. private String classPath; //完整类名
  3. private String name; //任务名称
  4. private String cron; //时间表达式
  5. private String description; //描述
  6. private Short status; //0启用 1停用
  7. }
  1. 创建定时任务抽象类AbstractJob,定义任务的创建、销毁、执行任务、获取任务名称等方法;

    **

    • @author liangxuelong
    • @version 1.0
    • @description: 定时任务抽象类
    • @date 2021/8/27 10:36
      */
      public abstract class AbstractJob implements Runnable {
  1. public Logger logger = LoggerFactory.getLogger(AbstractJob.class);
  2. private ScheduledFuture<?> scheduledFuture;
  3. @Autowired
  4. private ThreadPoolTaskScheduler threadPoolTaskScheduler;
  5. /**
  6. * 获取任务名称
  7. */
  8. public abstract String getName();
  9. /**
  10. * 开始执行任务
  11. */
  12. public abstract void execute();
  13. /**
  14. * @description: 创建定时任务
  15. * @param: cron 时间表达式
  16. * @return: void
  17. * @author liangxuelong
  18. * @date: 2021/8/27
  19. */
  20. public void createJob(String cron){
  21. try {
  22. scheduledFuture = threadPoolTaskScheduler.schedule(this, new CronTrigger(cron));
  23. } catch (Exception e) {
  24. logger.error("创建定时任务 【"+getName()+"】 失败!");
  25. e.printStackTrace();
  26. }
  27. }
  28. /**
  29. * 定时任务执行之前
  30. */
  31. public void begin(){
  32. logger.info("------开始执行【"+getName()+"】任务------");
  33. };
  34. /**
  35. * 定时任务执行之后
  36. */
  37. public void end(){
  38. logger.info("------结束执行【"+getName()+"】任务------");
  39. };
  40. /**
  41. * 取消执行任务
  42. */
  43. public void cancel(){
  44. try {
  45. if(scheduledFuture!=null)
  46. scheduledFuture.cancel(true);
  47. logger.info("取消执行【"+getName()+"】 任务!");
  48. } catch (Exception e) {
  49. logger.error("取消执行 【"+getName()+"】失败 !");
  50. e.printStackTrace();
  51. }
  52. }
  53. @Override
  54. public void run(){
  55. begin();
  56. execute();
  57. end();
  58. };
  59. }
  1. 创建定时任务SendMsgJob进行测试
    实现抽象类中抽象方法。加@Component交给spring

    /**

    • @author liangxuelong
    • @version 1.0
    • @description: 测试定时任务
    • @date 2021/8/26 14:04
      */
      @Component
      public class SendMsgJob extends AbstractJob {
  1. @Override
  2. public void execute() {
  3. logger.info("发送了一条消息");
  4. this.cancel();
  5. }
  6. @Override
  7. public String getName() {
  8. return "定时发送消息";
  9. }
  10. }
  1. 创建service 层完成添加、删除、修改、查询及立即执行定时任务
    这里是

    /**

    • @author liangxuelong
    • @version 1.0
    • @description: Scheduled service
    • @date 2021/8/16 9:07
      */
      @Service
      public class ScheduledServiceImpl extends ServiceImpl implements ScheduledService {
  1. @Autowired
  2. private ApplicationContext context;
  3. @Override
  4. public List<Scheduled> findAllScheduled() {
  5. return list();
  6. }
  7. /**
  8. * @description: 创建定时任务
  9. * @param: scheduled
  10. * @return: void
  11. * @author liangxuelong
  12. * @date: 2021/8/27
  13. */
  14. @Override
  15. @Transactional
  16. public void createJob(Scheduled scheduled) {
  17. AbstractJob job = null;
  18. try {
  19. job = (AbstractJob) context.getBean(Class.forName(scheduled.getClassPath()));
  20. } catch (ClassNotFoundException e) {
  21. e.printStackTrace();
  22. }
  23. if(job!=null){
  24. job.createJob(scheduled.getCron());
  25. }
  26. save(scheduled);
  27. }
  28. /**
  29. * @description: 修改定时任务
  30. * @param: scheduled
  31. * @return: void
  32. * @author liangxuelong
  33. * @date: 2021/8/27
  34. */
  35. @Override
  36. public void updateJob(Scheduled scheduled) {
  37. AbstractJob job = null;
  38. try {
  39. job = (AbstractJob) context.getBean(Class.forName(scheduled.getClassPath()));
  40. } catch (ClassNotFoundException e) {
  41. e.printStackTrace();
  42. }
  43. if(job!=null){
  44. job.cancel(); //先删除
  45. job.createJob(scheduled.getCron());//再创建
  46. }
  47. updateById(scheduled);
  48. }
  49. /**
  50. * @description: 立刻执行定时任务
  51. * @param: scheduled
  52. * @return: void
  53. * @author liangxuelong
  54. * @date: 2021/8/27
  55. */
  56. @Override
  57. public void executeJob(Scheduled scheduled) {
  58. AbstractJob job = null;
  59. try {
  60. job = (AbstractJob) context.getBean(Class.forName(scheduled.getClassPath()));
  61. } catch (ClassNotFoundException e) {
  62. e.printStackTrace();
  63. }
  64. if(job!=null){
  65. job.execute();
  66. }
  67. }
  68. /**
  69. * @description: 删除定时任务
  70. * @param: scheduled
  71. * @return: void
  72. * @author liangxuelong
  73. * @date: 2021/8/27
  74. */
  75. @Override
  76. public void deleteJob(Scheduled scheduled) {
  77. AbstractJob job = null;
  78. try {
  79. job = (AbstractJob) context.getBean(Class.forName(scheduled.getClassPath()));
  80. } catch (ClassNotFoundException e) {
  81. e.printStackTrace();
  82. }
  83. if(job!=null){
  84. job.cancel(); //删除
  85. removeById(scheduled.getId());
  86. }
  87. }
  88. }
  1. 实现SchedulingConfigurer接口创建定时任务配置类ScheduledConfig;
    实现configureTasks方法,用于程序启动完成对数据库里的定时任务进行创建;

    /**

    • @author liangxuelong
    • @version 1.0
    • @description: 定时任务配置类
    • @date 2021/8/25 9:40
      */
      @Configuration
      @EnableScheduling
      public class ScheduledConfig implements SchedulingConfigurer {
  1. @Autowired
  2. private ApplicationContext context;
  3. @Autowired
  4. private ScheduledService scheduledService;
  5. @Override
  6. public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
  7. //数据库查询到所有的定时任务
  8. List<Scheduled> scheduledList = scheduledService.findAllScheduled();
  9. //创建定时任务
  10. for (Scheduled scheduled : scheduledList) {
  11. AbstractJob task = null;
  12. try {
  13. task = (AbstractJob) context.getBean(Class.forName(scheduled.getClassPath()));
  14. } catch (ClassNotFoundException e) {
  15. e.printStackTrace();
  16. }
  17. task.createJob(scheduled.getCron());
  18. }
  19. }
  20. @Bean
  21. public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
  22. ThreadPoolTaskScheduler executor = new ThreadPoolTaskScheduler();
  23. executor.setPoolSize(20);
  24. executor.setThreadNamePrefix("taskExecutor-");
  25. executor.setWaitForTasksToCompleteOnShutdown(true);
  26. executor.setAwaitTerminationSeconds(60);
  27. return executor;
  28. }
  29. }
  1. 数据库添加一条数据进行测试
    在这里插入图片描述
    这里的classPath为包括类名的类完整路径;
    时间表达式cron可查看这里配置相应的时间表达式;这里的0/10 * * * * ? 每为10秒执行一次;
  2. 启动项目测试
    在这里插入图片描述

可以看见任务在第40秒已成功执行;由于我为了测试移除定时任务所以在SendMsgJob里的execute()方法里调用了cancel();所以执行一次之后定时任务就取消了。本地只是 为了测试方便,可以根据实际情况调用cancel()取消执行任务;

发表评论

表情:
评论列表 (有 0 条评论,132人围观)

还没有评论,来说两句吧...

相关阅读