Springboot集成quartz调度框架,同时可以在Job中直接使用@Autowired

6 篇文章 0 订阅

扯皮:

       Quartz是一个分布式任务调度框架,详细介绍请查询官网,避免误导大众。目前搜索结果被某些网站霸占,点击进去很难找到自己想要的结果。Spring本身也可以实现任务调度,简单的任务调度,可以用Spring的,复杂一点的只能使用Quartz了,网上的文章眼花缭乱,特别是很多恶心的网站复制来复制去,重复率那么高。

Springboot集成Quartz的步骤:

1. 添加Quartz依赖。

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
	<groupId>org.quartz-scheduler</groupId>
	<artifactId>quartz</artifactId>
	<version>2.3.2</version>
</dependency>

2. 实现Job类

@DisallowConcurrentExecution
public class ShellJob extends QuartzJobBean {

    @Autowired
    protected IWflowLaststatusTableService lastStatusService;
    // 历史日志
    @Autowired
    protected IWflowLogTableService logService;


    @Override
    public void executeInternal(JobExecutionContext context) throws JobExecutionException {
        System.out.println("executeInternal...................");
        // 约略了很多代码。
        // 模板是这样是这样自,里面用到了Autowired.
    }
}

如果直接实现Job接口,@Autowired永远只会返回null,别老折腾,QuartzJobBean实现了Job接口,除非你参照QuartzJobBean的实现,不然在Job里面用Autowired是不可能的。

3. 配置Quartz

spring:
  quartz:
    job-store-type: jdbc
    properties:
      org:
        quartz:
           scheduler:
             instanceName: JobScheduler
             instanceId: AUTO
           jobStore:
             class: org.quartz.impl.jdbcjobstore.JobStoreTX
             driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
             tablePrefix: QRTZ_
             isClustered: true
             useProperties: false
             dontSetAutoCommitFalse: true
           threadPool:
             class: org.quartz.simpl.SimpleThreadPool
             threadCount: 11
             threadPriority: 5
             threadsInheritContextClassLoaderOfInitializingThread: true

其中JobScheduler是实例的名字,相当于是集群名字,随便命名。

4. 添加任务调度器

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Date;
import java.util.Map;
import java.util.TimeZone;

@Component
public class JobSchedManageServiceImpl implements JobSchedManageService {

    static final Logger logger = LoggerFactory.getLogger(JobSchedManageServiceImpl.class);
    @Autowired
    private Scheduler mSched = null;
    

   // 省略了很多代码的


   


   /**
     * 启动任务调度 初始化调度
     *
     * @throws Exception
     */
    @PostConstruct
    public synchronized void start() {
        try {
            if (mSched == null) {
                mSched = getSched();
            }
            // 添加任务监听
            mSched.getListenerManager().addJobListener(logListener);
            // 添加触发器监听
            mSched.getListenerManager().addTriggerListener(jobTriggerListener);
            // 添加调度监听器
            mSched.getListenerManager().addSchedulerListener(jobSchedListener);
            if (!mSched.isStarted()) {
                mSched.start();
            }
        } catch (Exception e) {
            logger.error("启动调度失败", e);
        }
    }


    /**
     * 添加调度任务
     *
     * @param jobClass 执行任务的类
     * @param jobName  任务名称
     * @param jobGroup 任务组
     * @param entity   任务相关配置
     * @throws Exception
     */
    public synchronized void addJob(Class jobClass, String jobName, String jobGroup, JobSchedEntity entity)
            throws Exception {
        try {
            if (mSched == null) {
                mSched = getSched();
            }
            JobKey jobKey = new JobKey(jobName, jobGroup);
            if (mSched.checkExists(jobKey)) {
                mSched.deleteJob(jobKey);
            }
            //
            JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroup).build();
            jobDetail.getJobDataMap().put(JobSchedManageService.TASK_PROPERTIES, entity);
            // 0:不执行  1:执行一次,2: CRON表达式 3:简单触发器
            if (entity.getSchedType() == 0) {
                mSched.addJob(jobDetail, true);
            } else {
                TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroup);
                if (entity.getStartTime() != null) {
                    triggerBuilder.startAt(entity.getStartTime());
                } else {
                    triggerBuilder.startNow();
                }
                if (entity.getEndTime() != null) {
                    triggerBuilder.endAt(entity.getEndTime());
                }
                if (entity.getSchedType() == 1) {
                    // simpletrigger
                    triggerBuilder.withSchedule(SimpleScheduleBuilder.simpleSchedule());
                } else {
                    // entity.getSchedType() == 2
                    // CRON表达式
                    if (entity.getCronExpr() != null && entity.getCronExpr().trim().length() >= 0) {
                        //错过的周期不在触发
                        triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(entity.getCronExpr()).withMisfireHandlingInstructionDoNothing().inTimeZone(TimeZone.getTimeZone("Asia/Shanghai")));
                    } else {
                        // cron为空
                        triggerBuilder.withSchedule(SimpleScheduleBuilder.simpleSchedule().withMisfireHandlingInstructionNextWithExistingCount());
                    }
                }
                Trigger trigger = triggerBuilder.build();
                trigger.getJobDataMap().put(JobSchedManageService.WFLOW_ID,entity.getWflowId());
                trigger.getJobDataMap().put(JobSchedManageService.TRIGGER_PROPERTIES, entity);
                trigger.getJobDataMap().put(JobSchedManageService.SCHED_TYPE, ExecTypeEnum.PERIOD_EXEC.getValue());
                mSched.scheduleJob(jobDetail, trigger);
            }
        } catch (Exception e) {
            logger.error("add job catch exception:" + e.getMessage());
            throw e;
        }
    }
}

triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(entity.getCronExpr()).withMisfireHandlingInstructionDoNothing().inTimeZone(TimeZone.getTimeZone("Asia/Shanghai"))); 主要是确保时区的,不加的话,第一次执行会晚8个小时执行,其他代码就不贴了,已经把主要的贴出来了,上述代码仅供参考

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值