日常问题解决:使用Quartz定时调度,立即执行时参数获取异常的修复

一、前言

  一般项目时Quartz作为日常业务的定时调度,系统时间符合corn表达式后,系统自动执行对应的自定义job。某些业务场景下,在未到达指定时间时,需要该job立即执行。

二、定时任务一般执行

  一般所有业务类定时任务都会extends 公共定时任务执行方法BaseTimeJob 。BaseTimeJob extend QuartzJobBean,重写executeInternal方法,实现层增加相关日志信息的打印,如任务开始、结束、返回处理等。

public abstract class BaseZjJob extends QuartzJobBean {

protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        **//日志打印省略
        JobDetail jobDetail = jobExecutionContext.getJobDetail();
        String jobTask = jobDetail.getKey().getName();
        **//异常捕获省略
        log.info("Job " + jobTask + " start");
        ResultEnum resultEnum = this.taskPerform(jobExecutionContext);
        **//返回处理省略
        log.info("Job " + jobTask + " end");  
        
    }

}
protected abstract ResultEnum taskPerform(JobExecutionContext var1) throws Exception;
}

  一般业务类定时任务JobA ,则会Override如上taskPerform方法

public class JobA extends BaseTimeJob {
	@Override
	protected ResultEnum taskPerform(JobExecutionContext jobExecutionContext) throws Exception {

		//1.读取参数
		JobDetail jobDetail = jobExecutionContext.getJobDetail();
		String fileName= jobDetail.getJobDataMap().getString("fileName");

		**//业务实现逻辑
		return ResultEnum.SUCCEED;
	}
}

三、定时任务立即执行

     定时任务立即执行要求不影响其日常的常规触点执行,所以一般采用暴露给前端的接口完成。

public void executeJob(String jobName, String group, Map<String, Object> param) throws Exception {
        JobKey jobKey = JobKey.jobKey(jobName, group);
        JobDataMap jobDataMap = new JobDataMap(param);
        this.scheduler.triggerJob(jobKey, jobDataMap);//定时任务创建的sheduler
}

四、问题暴露与解决

  如上代码在实际测试中发现,立即执行调用时的参数无法在基本jobA中获取到,其仍然获取的是初始化加载的参数MAP。

      1)查看scheduler.triggerJob方法,其表述如下,即其传入的参数Map会置于job(也是个大Map)的第一层,key为jobDataMap。而我们一般初始化的默认参数是放在job下面的JobDetail中,key为jobDataMap,等于是第二层。

    /**
     * Trigger the identified <code>{@link org.quartz.JobDetail}</code>
     * (execute it now).
     * 
     * @param data the (possibly <code>null</code>) JobDataMap to be 
     * associated with the trigger that fires the job immediately. 
     */
    void triggerJob(JobKey jobKey, JobDataMap data)
        throws SchedulerException;

    2)解决方式,jobA任务执行是获取jobDataMao的方法更换为:getMergedJobDataMap();

    /**
     * <p>
     * Get the convenience <code>JobDataMap</code> of this execution context.
     * </p>
     * 
     * <p>
     * The <code>JobDataMap</code> found on this object serves as a convenience -
     * it is a merge of the <code>JobDataMap</code> found on the 
     * <code>JobDetail</code> and the one found on the <code>Trigger</code>, with 
     * the value in the latter overriding any same-named values in the former.
     * <i>It is thus considered a 'best practice' that the execute code of a Job
     * retrieve data from the JobDataMap found on this object.</i>
     * </p>
     * 
     * <p>NOTE: Do not expect value 'set' into this JobDataMap to somehow be set
     * or persisted back onto a job's own JobDataMap - even if it has the
     * <code>@PersistJobDataAfterExecution</code> annotation.
     * </p>
     * 
     * <p>
     * Attempts to change the contents of this map typically result in an 
     * <code>IllegalStateException</code>.
     * </p>
     * 
     */
    public JobDataMap getMergedJobDataMap();

     3)重试,问题解决!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

可乐欢丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值