• springboot动态定时任务


    SpringBoot设置动态定时任务

    一、说明

    1.在我们日常的开发中,很多时候,定时任务都不是写死的,而是写到数据库中,从而实现定时任务的动态配置。

    2.定时任务执行时间可根据数据库中某个设置字段动态改变。

    二、maven依赖

    <dependency>
                <groupId>org.quartz-scheduler</groupId>  
                <artifactId>quartz</artifactId>  
                <version>2.2.1</version>  
            </dependency>
            <dependency>
                <groupId>org.quartz-scheduler</groupId>
                <artifactId>quartz-jobs</artifactId>
                <version>2.2.1</version>
            </dependency>   
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
            </dependency>
    View Code

    三、代码

    1.输出测试类

    import org.quartz.JobExecutionException;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.EnableScheduling;
    import org.springframework.stereotype.Component;
    
    
    @Component
    @Configuration
    @EnableScheduling
    public class ScheduledJob {
    
        public void execute() throws JobExecutionException {
    
            System.out.println("hahaha");
        }
    
    }
    ScheduledJob

    2.Quartz配置类

    import org.quartz.Trigger;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
    import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
    import org.springframework.scheduling.quartz.SchedulerFactoryBean;
    
    @Configuration
    public class QuartzConfigration {
        /** 
         * attention: 
         * Details:配置定时任务 
         */  
        @Bean(name = "jobDetail")  
        public MethodInvokingJobDetailFactoryBean detailFactoryBean(ScheduledJob task) {// ScheduleTask为需要执行的任务  
            MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();  
            /* 
             *  是否并发执行 
             *  例如每5s执行一次任务,但是当前任务还没有执行完,就已经过了5s了, 
             *  如果此处为true,则下一个任务会执行,如果此处为false,则下一个任务会等待上一个任务执行完后,再开始执行 
             */  
            jobDetail.setConcurrent(false);  
              
            jobDetail.setName("srd-chhliu");// 设置任务的名字  
            jobDetail.setGroup("srd");// 设置任务的分组,这些属性都可以存储在数据库中,在多任务的时候使用  
              
            /* 
             * 为需要执行的实体类对应的对象 
             */  
            jobDetail.setTargetObject(task);  
              
            /* 
             * sayHello为需要执行的方法 
             * 通过这几个配置,告诉JobDetailFactoryBean我们需要执行定时执行ScheduleTask类中的sayHello方法 
             */  
            jobDetail.setTargetMethod("execute");  
            return jobDetail;  
        }  
          
        /** 
         * attention: 
         * Details:配置定时任务的触发器,也就是什么时候触发执行定时任务 
         */  
        @Bean(name = "jobTrigger")  
        public CronTriggerFactoryBean cronJobTrigger(MethodInvokingJobDetailFactoryBean jobDetail) {  
            CronTriggerFactoryBean tigger = new CronTriggerFactoryBean();  
            tigger.setJobDetail(jobDetail.getObject());  
            tigger.setCronExpression("0 10 15 * * ?");// 初始时的cron表达式  
            tigger.setName("srd-chhliu");// trigger的name  
            return tigger;  
      
        }  
      
        /** 
         * attention: 
         * Details:定义quartz调度工厂 
         */  
        @Bean(name = "schedulerTwo")  
        public SchedulerFactoryBean schedulerFactory(Trigger cronJobTrigger) {  
            SchedulerFactoryBean bean = new SchedulerFactoryBean();  
            // 用于quartz集群,QuartzScheduler 启动时更新己存在的Job  
            bean.setOverwriteExistingJobs(true);  
            // 延时启动,应用启动1秒后  
            bean.setStartupDelay(1);  
            // 注册触发器  
            bean.setTriggers(cronJobTrigger);  
            return bean;  
        }  
    }
    View Code

    3.定时请求数据库获取时间类 注意sql语句的更改及判断 查询频率可自行更改

    package com.jdkeji.shares.quartz;
    
    import javax.annotation.Resource;
    
    import org.mybatis.spring.SqlSessionTemplate;
    import org.quartz.CronScheduleBuilder;
    import org.quartz.CronTrigger;
    import org.quartz.JobDetail;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerException;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.EnableScheduling;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
    
    import com.jdkeji.shares.config.model.BusinessConfig;
    
    @Configuration  
    @EnableScheduling  
    @Component  
    public class ScheduleRefreshDatabase {
        @Autowired  
        private SqlSessionTemplate st;  
      
        @Resource(name = "jobDetail")  
        private JobDetail jobDetail;  
      
        @Resource(name = "jobTrigger")  
        private CronTrigger cronTrigger;  
      
        @Resource(name = "schedulerTwo")  
        private Scheduler scheduler;  
      
        @Scheduled(fixedRate = 5000) // 每隔5s查库,并根据查询结果决定是否重新设置定时任务  
        public void scheduleUpdateCronTrigger() throws SchedulerException {  
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey());  
            String currentCron = trigger.getCronExpression();// 当前Trigger使用的  
            BusinessConfig bc = st.selectOne("BusinessConfig.selectByExample");
            System.out.println(currentCron);  
            
            String [] date = bc.getClxg().split(":");
            String cron = "0 " + date[1] + " " + date[0] + " * * ?";
            System.out.println(cron);
            if (currentCron.equals(cron)) {  
                // 如果当前使用的cron表达式和从数据库中查询出来的cron表达式一致,则不刷新任务  
            } else {  
                // 表达式调度构建器  
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);  
                // 按新的cronExpression表达式重新构建trigger  
                trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey());  
                trigger = trigger.getTriggerBuilder().withIdentity(cronTrigger.getKey())  
                        .withSchedule(scheduleBuilder).build();  
                // 按新的trigger重新设置job执行  
                scheduler.rescheduleJob(cronTrigger.getKey(), trigger);  
                currentCron = cron;  
            }  
        }  
    }
    View Code

    四、注意

    QuartzConfigration类中的detailFactoryBean(ScheduledJob)

    ScheduledJob就是我们的输出测试类 

     

     

  • 相关阅读:
    java.util.ConcurrentModificationException 异常问题详解
    java1.8新特性整理(全)
    理解serialVersionUID是什么?有什么用?如何生成?
    数据结构与算法--->基础篇冒泡,选择,插入,希尔
    学习Java的第二天
    学习Java的第一天
    SpringBoot(2)—使用小技术总结
    SpringBoot(1)—相关工具使用
    json工具类(二)——google包
    json工具类(一)——alibaba包
  • 原文地址:https://www.cnblogs.com/weitaming/p/8359964.html
Copyright © 2020-2023  润新知