Quartz 之 scheduler 类的方法 【实现一个 quartz 管理类】

本文介绍适用于新版本Quartz的触发器管理类JobTriggerManagerServiceImpl,该类不再提供某些旧接口,如triggerJobWithVolatileTrigger,而是使用反射实现“立即触发功能”。文章详细展示了如何暂停、恢复和删除触发器,以及获取触发器信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

pause : 暂停一个触发器。如果是持久化的 quartz,此触发器的状态会被写到库中,哪怕是重启应用后,

也不会触发,因为状态是持久化的。

若更新 quartz 配置文件中的该触发器的属性,如 cron 表达式,则内存和数据库中已持久化的数据都不会被更新。


resume : 重置一个触发器的状态为运行状态,下次可调度。对一个不处于 pause 状态的触发器调用此方法无效果。此方法会改变触发器的持久化状态。


remove : 删除一个触发器(若是 cron 触发器,则它关联的 job 也会被删除),此处,删除的含义是,内存中删除,若是持久化 quartz,则库中的 trigger 和 job 也会被删除。

重启应用后,若原来的配置文件不变更,则被删除的 trigger 和 job 会被加回来,并且处于可触发的状态。


以下是完整的管理类。

package org.summer.spi.quartz;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.summer.exception.spe.SummerException;
import org.summer.spi.spe.JobTriggerManageService;

public class JobTriggerManagerServiceImpl implements JobTriggerManageService {

	private Scheduler scheduler;

	private final Logger logger = LoggerFactory.getLogger(this.getClass());
	public void setScheduler(Scheduler scheduler) {
		this.scheduler = scheduler;
	}
	
	public JobTriggerManagerServiceImpl() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public List> getQrtzTriggers()
	{
		try
		{
			String[] triggerGroupNames = scheduler.getTriggerGroupNames();
			List> triggersInfo = new ArrayList();		
			String[] triggerNames = null;
			Trigger trigger = null;		
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			for(int i=0;i curInfo = new HashMap<>();
					trigger = scheduler.getTrigger(triggerNames[j],triggerGroupNames[i]);
					if(trigger instanceof CronTrigger)
					{
						curInfo.put("cron", ((CronTrigger)trigger).getCronExpression());
					}
					else
					{
						curInfo.put("cron","非 cron 触发器");
					}
					
					curInfo.put("group", trigger.getGroup());
					curInfo.put("name", trigger.getName());
					curInfo.put("status", scheduler.getTriggerState(trigger.getName(), trigger.getGroup()));
					
					curInfo.put("lastTriggerTime", sdf.format(trigger.getPreviousFireTime()));
					curInfo.put("nextTriggerTime", sdf.format(trigger.getNextFireTime()));
					curInfo.put("startTriggerTime", sdf.format(trigger.getStartTime()));
					curInfo.put("endTriggerTime", null != trigger.getEndTime() ? sdf.format(trigger.getEndTime()) : "");
					
					triggersInfo.add(curInfo);
				}				
			}	
			return triggersInfo;
		}
		catch(Exception e)
		{
			throw new SummerException(e);
		}
	}

	@Override
	public void pauseTrigger(String triggerName, String group) {
		try {
			scheduler.pauseTrigger(triggerName, group);
		} catch (SchedulerException e) {
			throw new SummerException(e);
		}
	}

	@Override
	public void resumeTrigger(String triggerName, String group) {
		try {
			scheduler.resumeTrigger(triggerName, group);
		} catch (SchedulerException e) {
			throw new SummerException(e);
		}
	}

	@Override
	public void removeTrigger(String triggerName, String group){
		try {
			scheduler.unscheduleJob(triggerName, group);
		} catch (SchedulerException e) {
			throw new SummerException(e);
		}
	}

	@Override
	public String triggerRelativeJobsRightNow(String triggerName, String group){
		StringBuilder sb = new StringBuilder();
		try {
			String[] jobGroups = scheduler.getJobGroupNames();
			for(String curJobGroup : jobGroups)
			{
				String[] jobs = scheduler.getJobNames(curJobGroup);
				for(String job : jobs)
				{
					try
					{
						Trigger[] triggers = scheduler.getTriggersOfJob(job, curJobGroup);
						if(null != triggers && 1 == triggers.length && 
								triggers[0].getName().equals(triggerName)
								&& triggers[0].getGroup().equals(group))
						{
							scheduler.triggerJobWithVolatileTrigger(job, curJobGroup);
							sb.append(curJobGroup + "." + job).append(" | ");
						}
					}
					catch(Exception innerEx)
					{
						logger.warn("触发 job " + curJobGroup + "." + job + " 失败.",innerEx);
					}
				}
			}
		} catch (SchedulerException e) {
			throw new SummerException(e);
		}
		if(0 != sb.length())
			sb.delete(sb.length() - " | ".length(), sb.length());
		return sb.toString();
		
	}

}


以上管理类只适用于 1.8 及以下版本的 Quartz,对于新版本,Scheduler 不再提供一些方法,不再适用。下面给出适用于新版本的触发器管理类

package ---.---.---.service.impl;

/**
 *  和老版本 Quartz 的触发器管理类 JobTriggerManagerServiceImpl.java 的实现不一样,新版本的 Quartz 减少了一些接口,加入了新接口。
 *  如不再提供 triggerJobWithVolatileTrigger 方法。“立即触发功能” 可以使用 java 反射做。 
 * 
 */

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.webank.mbp.ccsm.service.JobTriggerManageService;

import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class JobTriggerManagerServiceImpl implements JobTriggerManageService,ApplicationContextAware {

    @Autowired
    SchedulerFactoryBean schedulerFactoryBean;
    
    private static ApplicationContext applicationContext; // Spring应用上下文环境

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
          this.applicationContext = applicationContext;
    }
    
	public JobTriggerManagerServiceImpl() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public List> getQrtzTriggers() throws SchedulerException
	{
	    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	    Scheduler scheduler = schedulerFactoryBean.getScheduler();
	    GroupMatcher matcher = GroupMatcher.anyTriggerGroup();
	    Set triggerKeys = scheduler.getTriggerKeys(matcher);
		List triggerGroupNames = scheduler.getTriggerGroupNames();
		List> triggersInfo = new ArrayList();
		for(TriggerKey key : triggerKeys)
		{		    
		    Trigger trigger = scheduler.getTrigger(key);
		    
		    Map curInfo = new HashMap<>();
		    if(trigger instanceof CronTrigger)
            {
                curInfo.put("cron", ((CronTrigger)trigger).getCronExpression());
            }
            else
            {
                curInfo.put("cron","非 cron 触发器");
            }
            
            curInfo.put("group",key.getGroup());
            curInfo.put("name", key.getName());
            curInfo.put("status", scheduler.getTriggerState(key));
            
            curInfo.put("lastTriggerTime", null != trigger.getPreviousFireTime() ? sdf.format(trigger.getPreviousFireTime()) : "");
            curInfo.put("nextTriggerTime", null != trigger.getNextFireTime() ? sdf.format(trigger.getNextFireTime()) : "");
            curInfo.put("startTriggerTime", null != trigger.getStartTime() ? sdf.format(trigger.getStartTime()) : "");
            curInfo.put("endTriggerTime", null != trigger.getEndTime() ? sdf.format(trigger.getEndTime()) : "");
            
            triggersInfo.add(curInfo);
		}
		return triggersInfo;
	}

	@Override
	public void pauseTrigger(String triggerName, String group) throws SchedulerException{
		 schedulerFactoryBean.getScheduler().pauseTrigger(new TriggerKey(triggerName, group));
	}

	@Override
	public void resumeTrigger(String triggerName, String group) throws SchedulerException{
		schedulerFactoryBean.getScheduler().resumeTrigger(new TriggerKey(triggerName, group));
	}

	@Override
	public void removeTrigger(String triggerName, String group) throws SchedulerException{
	    Set keys = getStrictRelativeJob(triggerName, group);
	    
		schedulerFactoryBean.getScheduler().unscheduleJob(new TriggerKey(triggerName, group));
		List keyList = new ArrayList<>();
		keyList.addAll(keys);
		schedulerFactoryBean.getScheduler().deleteJobs(keyList);
	}
	
	/*
	 * 获得一个 trigger 强关联的 job. 即 job 只与这一个 trigger 相关联
	 */
	private Set getStrictRelativeJob(String triggerName, String group) throws SchedulerException
	{
	    Set rets = new HashSet<>();
	    Scheduler scheduler = schedulerFactoryBean.getScheduler();
	    TriggerKey target = new TriggerKey(triggerName, group);
        Set jobKeys = scheduler.getJobKeys(GroupMatcher.anyJobGroup());//GroupMatcher.jobGroupEquals(group)
        for(JobKey key : jobKeys)
        {
            List triggers = (List) scheduler.getTriggersOfJob(key);
            if(null != triggers && 1 == triggers.size() 
                    && triggers.get(0).getKey().equals(target))
            {
                rets.add(key);
            }
        }
        return rets;
	}
	
	private void triggerRightNow(JobKey jobKey) throws SchedulerException
    {
	    Scheduler scheduler = schedulerFactoryBean.getScheduler();
	    Class jobClass = scheduler.getJobDetail(jobKey).getJobClass();
	    Job jobObj = (Job)applicationContext.getBean(jobClass);
	    
	    try
	    {
	        Method targetMethod = jobClass.getDeclaredMethod("executeInternal", new Class[] {JobExecutionContext.class});
	        targetMethod.setAccessible(true);
	        targetMethod.invoke(jobObj, new Object[]{null});
	        targetMethod.setAccessible(false);
	    } 
	    catch(Exception e)
	    {
	        throw new SchedulerException(e);
	    }
    }
	
	@Autowired
	ObjectMapper json;
	@Override
	public String triggerRelativeJobsRightNow(String triggerName, String group)throws SchedulerException{
		StringBuilder sb = new StringBuilder();

	    Scheduler scheduler = schedulerFactoryBean.getScheduler();
	    Trigger trigger = scheduler.getTrigger(new TriggerKey(triggerName, group));
	    
	    Set jobKeys = getStrictRelativeJob(triggerName, group);
	    for(JobKey key : jobKeys)
	    {
	        triggerRightNow(key);
            sb.append(key.getGroup() + "." + key.getName()).append(" | ");
	    }

		if(0 != sb.length())
			sb.delete(sb.length() - " | ".length(), sb.length());
		return sb.toString();
	}
}

在Spring Boot应用中,使用`spring-boot-starter-quartz`依赖引入Quartz Scheduler[^1],你可以通过Spring自动配置来轻松地集成它。Spring Boot简化了设置,不需要手动配置Scheduler。主要的包括`org.quartz.Scheduler`,这是整个调度系统的中心,负责管理和执行安排的工作。 以下是一个简单的示例,展示了如何在Spring Boot中启动并使用`Scheduler`: ```java // 引入Spring Boot的Quartz Starter @SpringBootApplication public class Application { @Autowired private Scheduler scheduler; public static void main(String[] args) { SpringApplication.run(Application.class, args); } // 在初始化时启动scheduler @PostConstruct public void startScheduler() { try { // 启动调度器 scheduler.start(); System.out.println("Scheduler started successfully"); } catch (SchedulerException e) { throw new RuntimeException("Error starting scheduler", e); } } // 创建并安排Job(任务) public void scheduleJob(Runnable jobDetails) { // 使用JobDetailBuilder构建JobDetail对象 JobDetail job = JobBuilder.newJob(RunnableJob.class) .withIdentity("jobName", "group") .build(); // 使用TriggerBuilder构建Trigger对象 Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("triggerName", "group") .startAt(DateUtil.addSeconds(new Date(), 5)) .build(); // 将Job和Trigger提交到Scheduler实例中执行 scheduler.scheduleJob(job, trigger); } } ``` 在这个例子中,`RunnableJob.class`是你自定义的一个实现了`org.quartz.Job`接口的,用于封装你的实际业务逻辑[^2]。`scheduleJob`方法会安排这个任务在5秒后开始执行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值