quartz job与spring 1.x和 spring 2.x的集成

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/longqicsdn/article/details/86583702

首先引入依赖包:

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

接着实现写spirng boot的quartz配置类 QuartzJobConfig ,具体如下:

package com.draco.bootdemo.common.config;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.draco.bootdemo.common.component.quartzjob.BaseJob;
import com.draco.bootdemo.common.component.quartzjob.BootDemoJobFactory;
import com.draco.bootdemo.model.TaskJobInfo;
import com.draco.bootdemo.service.TaskJobInfoService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description 定时任务配置类
 * @Author LongQi
 * @CreateTime 2019/1/11 15:37
 */
@Slf4j
@Configuration
public class QuartzJobConfig {

    public static final List<BaseJob> JOB_LIST = new ArrayList<>();

    @Autowired
    private BootDemoJobFactory bootDemoJobFactory;

    @Autowired
    private DataSource dataSource;

    @Autowired
    private TaskJobInfoService taskInfoService;

    @Bean(destroyMethod = "destroy",autowire = Autowire.NO)
    public SchedulerFactoryBean schedulerFactoryBean(){
        SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
        initJobAndTrigger(factoryBean);
        factoryBean.setJobFactory(bootDemoJobFactory);
        //factoryBean.setDataSource(dataSource);
        //factoryBean.setConfigLocation(new ClassPathResource("/quartz.properties"));
        factoryBean.setAutoStartup(true);
        factoryBean.setOverwriteExistingJobs(true);
        return factoryBean;
    }

    private void initJobAndTrigger(SchedulerFactoryBean schedulerFactoryBean) {
        QueryWrapper<TaskJobInfo> taskQuery = new QueryWrapper<>();
        taskQuery.in("STATUS",1,2);  //未开始和进行中的job
        taskQuery.orderByAsc("NAME");
        List<TaskJobInfo> tasks = taskInfoService.list(taskQuery);

        Map<String,List<String>> jobCronMap = new HashMap<>();
        for(TaskJobInfo task : tasks){
            if(jobCronMap.keySet().contains(task.getName())){
                jobCronMap.get(task.getName()).add(task.getCronExpression());
            }else{
                List<String> cronList = new ArrayList<>();
                cronList.add(task.getCronExpression());
                jobCronMap.put(task.getName(), cronList);
            }
        }

        JobDetail[] jobDetails = new JobDetail[JOB_LIST.size()];
        Trigger[] triggers = new Trigger[tasks.size()];
        int triggerCount = 0;
        for (int i=0;i<JOB_LIST.size();i++) {
            String jobName = JOB_LIST.get(i).getClass().getName();
            JobDetail jobDetail = JobBuilder.newJob(JOB_LIST.get(i).getClass())
                    .withIdentity(jobName, "jobGroup")
                    .storeDurably(true)
                    .requestRecovery(true)
                    .build();
            List<String> cronList = jobCronMap.get(jobName);
            if(cronList !=null && !cronList.isEmpty()){
                jobDetails[i] = jobDetail;
                for(int j=0;j<cronList.size();j++){
                    Trigger trigger = TriggerBuilder.newTrigger()
                            .withIdentity(jobName + ".Trigger"+j, "triGroup")
                            .forJob(jobName, "jobGroup")
                            .withSchedule(CronScheduleBuilder.cronSchedule(cronList.get(j)))
                            //.withSchedule(CronScheduleBuilder.cronSchedule(cronList.get(j)).withMisfireHandlingInstructionFireAndProceed())
                            .build();
                    triggers[triggerCount] = trigger;
                    triggerCount ++;
                }
            }
        }
        schedulerFactoryBean.setJobDetails(jobDetails);
        schedulerFactoryBean.setTriggers(triggers);
    }

}

接着配置SpringBeanJobFactory,用于spring容器注入job

/**
 * @Description job注入使用
 * @Author LongQi
 * @CreateTime 2019/1/21 12:43
 */
@Component("bootDemoJobFactory")
public class BootDemoJobFactory extends SpringBeanJobFactory {

    @Autowired
    private AutowireCapableBeanFactory capableBeanFactory;

    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        Object jobInstance = super.createJobInstance(bundle);
        capableBeanFactory.autowireBean(jobInstance);
        return jobInstance;
    }
}

job的基本父类如下:

/**
 * @Description job抽象类,自定义job只要继承该类并实现run()即可
 * @Author LongQi
 * @CreateTime 2019/1/12 12:52
 */
@Slf4j
public abstract class BaseJob implements Job{

    @PostConstruct
    public void init(){
        QuartzJobConfig.JOB_LIST.add(this);
    }

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        Long beginTime = System.currentTimeMillis();
        log.info(this.getClass().getName()+"开始运行任务...");
        run(jobExecutionContext);
        log.info(this.getClass().getName()+"结束运行任务。总耗时:"+(System.currentTimeMillis()-beginTime)+"ms!");
    }

    /**
     * 实现job运行的业务逻辑
     * @param jobExecutionContext
     */
    public abstract void run(JobExecutionContext jobExecutionContext);
}

具体job类如下:

package com.draco.bootdemo.common.component.quartzjob.job;

import com.draco.bootdemo.common.component.quartzjob.BaseJob;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.stereotype.Component;

/**
 * @Description 定时任务
 * @Author LongQi
 * @CreateTime 2019/1/12 14:43
 */
@Component
public class DemoJob extends BaseJob {

    @Override
    public void run(JobExecutionContext context) {
        System.out.println("执行job,此次对应的cron表达式为:"+context.getTrigger().getKey());
    }
}

写完上面几个类后,数据库里建立如下表:

##quartz - job  业务job表
/*==============================================================*/
/* DBMS name:      MySQL 5.0                                    */
/* Created on:     2019/1/21 20:42:33                           */
/*==============================================================*/


drop table if exists TASK_JOB_INFO;

/*==============================================================*/
/* Table: TASK_JOB_INFO                                         */
/*==============================================================*/
create table TASK_JOB_INFO
(
   ID                   bigint comment '主键ID',
   NAME                 varchar(150) comment 'JOB名称(一般是job的class名称)',
   CRON_EXPRESSION      varchar(50) comment 'CRON表达式',
   TRIGGER_TIME         datetime comment '触发时间',
   STATUS               tinyint comment '状态(1:未开始  2:进行中  3:已结束 )',
   CREATOR              bigint comment '创建人',
   MODIFIER             bigint comment '修改人',
   CREATE_TIME          datetime comment '创建时间',
   MODIFY_TIME          datetime comment '修改时间'
);

alter table TASK_JOB_INFO comment '任务Job表';

最上面的taskInfoService是TASK_JOB_INFO表对应的表接口,用于查询要进行的任务

猜你喜欢

转载自blog.csdn.net/longqicsdn/article/details/86583702
今日推荐