天天看點

quarz+springBoot 定時任務

文章目錄

    • 引入jar
    • 建表
    • 配置quartz.properties
    • JobFactory
    • 任務初始化

引入jar

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

建表

quarz+springBoot 定時任務

配置quartz.properties

# 固定字首org.quartz
# 主要分為scheduler、threadPool、jobStore、plugin等部分
#執行個體名
org.quartz.scheduler.instanceName=Scheduler
#執行個體id(唯一,有預設值)
org.quartz.scheduler.instanceId=SchedulerId
org.quartz.scheduler.rmi.export=false
org.quartz.scheduler.rmi.proxy=false
org.quartz.scheduler.wrapJobExecutionInUserTransaction=false
# 執行個體化ThreadPool時,使用的線程類為SimpleThreadPool
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
# 并發個數
org.quartz.threadPool.threadCount=5
# 優先級
org.quartz.threadPool.threadPriority=5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true
org.quartz.jobStore.misfireThreshold=5000
# 預設存儲在記憶體中
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
           
import org.quartz.Scheduler;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
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 java.io.IOException;
import java.util.Properties;


@Configuration
public class SchedulerConfig {
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        schedulerFactoryBean.setQuartzProperties(quartzProperties());
        return schedulerFactoryBean;
    }
    @Bean
    public Properties quartzProperties() throws IOException {
        PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
        propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
        //在quartz.properties中的屬性被讀取并注入後再初始化對象
        propertiesFactoryBean.afterPropertiesSet();
        return propertiesFactoryBean.getObject();
    }

    /*
     * quartz初始化監聽器
     */
    @Bean
    public QuartzInitializerListener executorListener() {
        return new QuartzInitializerListener();
    }

    /*
     * 通過SchedulerFactoryBean擷取Scheduler的執行個體
     */
    @Bean(name="Scheduler")
    public Scheduler scheduler() throws IOException {
        return schedulerFactoryBean().getScheduler();
    }
}

           

JobFactory

import com.alibaba.fastjson.JSONObject;
import com.inspur.ssp.supervise.bean.entity.SupJob;
import com.inspur.ssp.supervise.constant.Constant;
import org.apache.commons.lang.StringUtils;
import org.jangod.iweb.util.DaoFactory;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


@DisallowConcurrentExecution
public class JobFactory implements Job{

    private static Logger logger = LoggerFactory.getLogger(Constant.LOG_TYPE_JOB);

    //預設執行入口
    private static final String METHOD = "execute";

    public JobFactory(){

    }

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        SupJob jobBean = (SupJob)context.getMergedJobDataMap().get("scheduleJob");
        long start = System.currentTimeMillis();
        logger.info("定時任務【"+ jobBean.getName()+"】開始執行,執行時間:"+new Date());
        String action = jobBean.getAction();
        String method = jobBean.getMethod();
        if(StringUtils.isEmpty(method)){
            method = METHOD;
        }
        try {
            Class clazz = DaoFactory.getClass(action);
            Method[] methods = clazz.getMethods();//全部方法
            for(Method _method : methods){
                if(method.equals(_method.getName())){
                    Class<?>[] cls = _method.getParameterTypes();
                    if(cls.length == 0){
                        DaoFactory.invoke(action,method,cls,new Object[]{});
                    }else{
                        Map<String,Object> params = (Map<String,Object>)JSONObject.parse(jobBean.getParam());
                        if(null == params) {
                            params = new HashMap<>();
                        }
                        params.put("params",jobBean.getParam());
                        DaoFactory.invoke(action,method,cls,new Object[]{params});
                    }
                }
            }
        } catch (Exception e) {
            logger.error("執行定時任務【"+jobBean.getName()+"】出錯,",e);
        }finally {
            long end = System.currentTimeMillis();
            logger.info("定時任務【"+ jobBean.getName()+"】執行結束,耗時:"+((end-start)/1000)+"s");
        }


    }
}

           

任務初始化

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.inspur.ssp.supervise.bean.entity.SupJob;
import com.inspur.ssp.supervise.job.JobFactory;
import com.inspur.ssp.supervise.mapper.SupJobMapper;
import com.inspur.ssp.supervise.service.ISupJobService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;


@Service
@Transactional
public class SupJobServiceImpl extends ServiceImpl<SupJobMapper, SupJob> implements ISupJobService {
    private static final String GROUP = "_group";
    @Autowired @Qualifier("Scheduler")
    private Scheduler scheduler;


    @Override
    public void initJob() throws Exception{
        //擷取任務清單
        QueryWrapper<SupJob> queryWrapper= new QueryWrapper<SupJob>();
        queryWrapper.eq("STATUS", "1");
        List<SupJob> supJobs = this.baseMapper.selectList(queryWrapper);
        for (SupJob jobBean : supJobs) {
            //任務名稱和任務組設定規格
            String jobId = jobBean.getId();
            String jobGroup=jobId+GROUP;

           //觸發器
            TriggerKey triggerKey = TriggerKey.triggerKey(jobId, jobGroup);
            CronTrigger trigger = (CronTrigger)scheduler.getTrigger(triggerKey);
            //觸發器不存在 則建立
            if(trigger==null){
                JobDetail jobDetail = JobBuilder.newJob(JobFactory.class).withIdentity(jobId, jobGroup).build();
                jobDetail.getJobDataMap().put("scheduleJob",jobBean);
                //表達式排程器建構
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(jobBean.getCron());
                //按新的表達式建構一個新的觸發器
                trigger = TriggerBuilder.newTrigger().withIdentity(jobId, jobGroup).withSchedule(scheduleBuilder).build();
                scheduler.scheduleJob(jobDetail,trigger);
            }else{
                //觸發器已存在,則更新相應的定時設定
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(jobBean.getCron());
                //按照新的表達式重新建構觸發器
                trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
                //按照新的觸發器重新設定job執行
                scheduler.rescheduleJob(triggerKey,trigger);
            }
        }

    }


    /**
     * 擷取job key
     * @param jobId
     * @return
     */
    private JobKey getJobKey(String jobId) {
        String jobGroup = jobId+GROUP;
        return JobKey.jobKey(jobId,jobGroup);
    }

    @Override
    public void deleteJob(String id)throws Exception{
        JobKey jobKey = this.getJobKey(id);
        scheduler.deleteJob(jobKey);
    }


    /**
     * 新增任務
     * @param supJob
     * @throws Exception
     */
    @Override
    public void insertJob(SupJob supJob)throws Exception {
        String jobId = supJob.getId();
        String jobGroup = jobId+GROUP;

        TriggerKey triggerKey = TriggerKey.triggerKey(jobId,jobGroup);
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

        JobDetail jobDetail = JobBuilder.newJob(JobFactory.class).withIdentity(jobId,jobGroup).build();
        jobDetail.getJobDataMap().put("scheduleJob", supJob);
        // 表達式排程建構器
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(supJob.getCron());
        // 按新的表達式建構一個新的trigger
        trigger = TriggerBuilder.newTrigger().withIdentity(jobId, jobGroup).withSchedule(scheduleBuilder).build();
        scheduler.scheduleJob(jobDetail, trigger);
    }

}

           

學習連結

繼續閱讀