SpringBoot整合QuartZ任务调度

1、Quartz的3个基本要素

  1. Scheduler:调度器。所有的调度都是由它控制。
  2. Trigger: 触发器。决定什么时候来执行任务。
  3. JobDetail & Job: JobDetail定义的是任务数据,而真正的执行逻辑是在Job中。使用JobDetail + Job而不是Job,这是因为任务是有可能并发执行,如果Scheduler直接使用Job,就会存在对同一个Job实例并发访问的问题。而JobDetail & Job 方式,sheduler每次执行,都会根据JobDetail创建一个新的Job实例,这样就可以规避并发访问的问题。

1、添加QuartZ依赖

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

2、注入Bean

@Configuration
public class QuartzConfigration{

    @Bean(name = "jobDetail")
    public MethodInvokingJobDetailFactoryBean detailFactoryBean(WsdlTask task) {
        MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
        /*
         *  是否并发执行
         *  例如每5s执行一次任务,但是当前任务还没有执行完,就已经过了5s了,
         *  如果此处为true,则下一个任务会执行,如果此处为false,则下一个任务会等待上一个任务执行完后,再开始执行
         */
        jobDetail.setConcurrent(false);
        jobDetail.setName("wsdl-getRawMaterial");
        jobDetail.setGroup("wsdl");
        jobDetail.setTargetObject(task);
        jobDetail.setTargetMethod("getRawMaterial");
        return jobDetail;
    }

    /**
     * attention:
     * Details:配置定时任务的触发器,也就是什么时候触发执行定时任务
     */
    @Bean(name = "jobTrigger")
    public CronTriggerFactoryBean cronJobTrigger(MethodInvokingJobDetailFactoryBean jobDetail) {
        CronTriggerFactoryBean tigger = new CronTriggerFactoryBean();
        tigger.setJobDetail(Objects.requireNonNull(jobDetail.getObject()));
        tigger.setCronExpression("0/2 * * * * ? ");
        tigger.setName("wsdl-getRawMaterial");
        return tigger;

    }

    /**
     * attention:
     * Details:定义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;
    }
}

3、数据库控制

@Component
public class ScheduleRefresh {
    @Resource(name = "jobTrigger")
    private CronTrigger cronTrigger;

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

    private final JPAQueryFactory jpaFactory;
    private final QSystemConfig qSystemConfig;
    private static final String ON = "on";
    private static final String OFF = "off";

    public ScheduleRefresh(BaseDao dao) {
        this.jpaFactory = new JPAQueryFactory(dao.getEntityManager());
        this.qSystemConfig = QSystemConfig.systemConfig;
    }

    /**
     * @description: 每隔5s查库,并根据查询结果决定是否重新设置定时任务
     * @params:
     * @return:
     * @auther: WZH
     * @date: 2019/12/16 17:00
     */
    @Scheduled(fixedRate = 5000)
    public void scheduleUpdateCronTrigger() throws SchedulerException {
        TriggerKey triggerKey = cronTrigger.getKey();
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        String rawMaterialOn = "rawMaterialOn";
        String searchOn = jpaFactory.select(qSystemConfig.value).from(qSystemConfig).where(qSystemConfig.name.eq(rawMaterialOn)).fetchFirst();
        Trigger.TriggerState state = scheduler.getTriggerState(triggerKey);
        if(state== Trigger.TriggerState.NORMAL&& OFF.equals(searchOn)){
            //暂停定时器
            System.out.println(state);
            System.out.println("暂停定时器--------------------");
            scheduler.pauseTrigger(triggerKey);
        }else if (state==Trigger.TriggerState.PAUSED&&ON.equals(searchOn)){
            //恢复定时器
            System.out.println(state);
            System.out.println("恢复定时器--------------------");
            scheduler.resumeTrigger(triggerKey);
        }
        if(state==Trigger.TriggerState.NORMAL&&ON.equals(searchOn)){
            //当前执行周期
            String currentCron = trigger.getCronExpression();
            //从数据库查询出来的
            String rawMaterialCron = "rawMaterialCron";
            String searchCron = jpaFactory.select(qSystemConfig.value).from(qSystemConfig).where(qSystemConfig.name.eq(rawMaterialCron)).fetchFirst();
            if (!currentCron.equals(searchCron)) {
                // 表达式调度构建器
                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);
            }
        }
    }
}

4、具体业务类

@Service
public class WsdlTask {
	public void getRawMaterial(){
        System.out.println("测试QuartZ---------"+new Date());
    }
}

5、Quartz中Job和Trigger的执行状态

STATE_BLOCKED 4 阻塞 
STATE_COMPLETE 2 完成 
STATE_ERROR 3 错误 
STATE_NONE -1 不存在 
STATE_NORMAL 0 正常 
STATE_PAUSED 1 暂停

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值