天天看点

【动态定时任务】从apollo配置中心获取定时任务的执行时间,能够实时修改定时任务执行时间

基本原理:设置两次定时任务,一次定时任务专门用来查看apollo的配置是否修改。另一次则是项目需要执行的定时任务

废话不多说,直接上代码,走着

一、引入依赖

<!--        引入quartz依赖-->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
        </dependency>

        <!-- 该依赖必加,里面有sping对schedule的支持 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
           

二、需要执行的定时任务

@Configuration
@Component
@EnableScheduling
public class TaskConfig {

    public void reset(){  //需要执行的定时任务
        //定时任务的业务代码XXXXXXXXXXXXXXXXXXXXXX
    }

}
           

三、Quartz配置类

@Configuration
public class QuartzConfigration {

    @Bean(name = "jobDetail")
    public MethodInvokingJobDetailFactoryBean detailFactoryBean(TaskConfig taskConfig){  //需要定时执行的任务

        MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
        /*
         *  是否并发执行
         *  例如每5s执行一次任务,但是当前任务还没有执行完,就已经过了5s了,
         *  如果此处为true,则下一个任务会执行,如果此处为false,则下一个任务会等待上一个任务执行完后,再开始执行
         */
        jobDetail.setConcurrent(false);  //等待上一个任务执行完,再开始执行
        jobDetail.setName("resetTask"); //设置任务的名字
        jobDetail.setTargetObject(taskConfig); //为需要执行的实体类对应的对象(定时方法所在类的对象)
        jobDetail.setTargetMethod("reset"); // 为需要执行的方法(需要执行的定时任务方法)
        return jobDetail;
    }

    /**
     * attention:
     * Details:配置定时任务的触发器,也就是什么时候触发执行定时任务
     */
    @Bean(name = "jobTrigger")
    public CronTriggerFactoryBean cronJobTrigger(MethodInvokingJobDetailFactoryBean jobDetail){
        CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
        trigger.setJobDetail(jobDetail.getObject());
        trigger.setCronExpression("0 0 0 * * ?"); //初始时的cron表达式
        trigger.setName("resetTask"); // trigger的name
        return trigger;
    }

    /**
     *
     * @param cronJobTrigger
     * @return 定义quartz调度工厂
     */
    @Bean(name = "scheduler")
    public SchedulerFactoryBean schedulerFactory(Trigger cronJobTrigger){
        SchedulerFactoryBean bean = new SchedulerFactoryBean();
        // 用于quartz集群,QuartzScheduler 启动时更新己存在的Job
        bean.setOverwriteExistingJobs(true);
        // 延时启动,应用启动1秒后
        bean.setStartupDelay(1);
        // 注册触发器
        bean.setTriggers(cronJobTrigger);
        return bean;
    }
}
           

四、获取定时任务动态执行时间

@Configuration
@EnableScheduling
@Component
public class ScheduleRefreshApollo {

    @Resource(name = "jobDetail")
    private JobDetail jobDetail;

    @Resource(name = "jobTrigger")
    private CronTrigger cronTrigger;

    @Resource(name = "scheduler")
    private Scheduler scheduler;

    @Scheduled(fixedDelay = 60000) //每隔1分钟,获取apollo数据,决定是否重置定时任务
    public void scheduleUpdateCronTrigger() throws SchedulerException {
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey());
        String currentCron = trigger.getCronExpression();//当前trigger使用的
        String searchCron = SystemConfigValues.get("job.cron");//获取apollo配置的时间,这里是公司封装的方法,需要修改为自己的动态时间 
        System.out.println(">>>>>>>>>>currentCron>>>>>>>>>>>" + currentCron + ",searchCron>>>>>>>>>>>" + searchCron);
        if (null != searchCron && null!=currentCron && !searchCron.equals(currentCron)){
            // 表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(searchCron);
            // 按新的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 = searchCron;
        }
    }
}