spring和quartz整合

本文介绍了一种使用Spring框架结合Quartz实现的定时任务管理系统。系统通过JobManager工具类进行任务的增删改查操作,并利用JobWrapper类通过反射调用业务类的方法来执行具体任务。此外,还提供了一个业务类示例,展示了如何实现任务的执行及状态回调。

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

之前业务的定时任务在spring中的配置文件中,先通过quartz表进行任务管理,支持集群。

只说单任务,

先写一个JobManager工具类,用来对job操作。

然后写一个JobWrapper包装类,实现job接口,在excute方法中通过反射调用业务的方法,这样子业务就不用实现接口或者继承类,之前的类可以直接使用。

并且JobWrapper实现了IScheduleJobListener接口,里面提供了两个回调方法,这样子任务的状态可以由业务自己控制。


JobManager工具类,对任务的添加、删除、暂停和恢复、注册。

package com.schedule.framework;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

import org.apache.log4j.Logger;
import org.quartz.CronTrigger;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.context.ApplicationContext;

import com.schedule.ScheConstant;
import com.schedule.framework.util.ScheduleMethodInvokingJobDetailFactoryBean;

public class JobManager {
	
	private static SchedulerFactory gSchedulerFactory = new StdSchedulerFactory();
	private static final Logger logger=Logger.getLogger(JobManager.class);
	//单一job JOB_NAME=UUID	TRIGGER_NAME="TRIGGER_NAME"+UUID
	public static String JOB_GROUP = "MHIS_DEFAULT_JOBGROUP";
	public static String TRIGGER_GROUP="MHIS_DEFAULT_TRIGGERGROUP";
	
	
	/**
	 * 任务组
	 * String JOB_NAME=UUID;
	 * String JOB_GROUP="JOB_GROUP"+UUID;(根job的UUID作为这个任务组的job_group)
	 * String TRIGGER_NAME="TRIGGER_NAME"+UUID;
	 * String TRIGGER_GROUP="TRIGGER_GROUP"+UUID;(根job的UUID作为这个任务组的job_group)
	 */
	
	/***
	 * 启动单任务job 
	 * @param jobName 任务名
	 * @param triggerExp 触发器表达式
	 */
	@SuppressWarnings("unchecked")
	public static void startSingleJob(String jobName,String triggerExp,boolean IsRequestsRecovery){
		
		try {
			Scheduler sched = gSchedulerFactory.getScheduler();
			JobDetail jobDetail = new JobDetail();
			CronTrigger trigger = new CronTrigger();
//			if(JobManager.JOB_GROUP.equals(jobGroupName)){//				
//							
//			}
			jobDetail.setName(jobName);
			jobDetail.setGroup(JobManager.JOB_GROUP);
			jobDetail.setDurability(true);
			jobDetail.setRequestsRecovery(IsRequestsRecovery);
			jobDetail.setJobClass(JobWrapper.class);			
			trigger.setName(ScheConstant.TRIGGER_NAME + jobName);
			trigger.setGroup(JobManager.TRIGGER_GROUP);	
			trigger.setCronExpression(triggerExp);
			
			sched.scheduleJob(jobDetail, trigger);
			// 启动
			if (sched.isShutdown()) {
				sched.start();
				logger.info("添加单一任务"+jobName+"成功");
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	/****
	 * 添加job到容器
	 * @param jobName
	 * @param jobGroupName
	 * @param jobClass 包路径
	 */
	public static void addJobToTaskList(String jobName,String jobGroupName,Class jobClass){
		try {
			Scheduler sched = gSchedulerFactory.getScheduler();
			JobDetail jobdetail = new JobDetail(jobName, jobGroupName, jobClass);
			jobdetail.setDurability(true);
			jobdetail.setRequestsRecovery(true);
			sched.addJob(jobdetail, true);
		} catch (SchedulerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/****
	 * 为job添加触发器
	 * @param triggerName
	 * @param triggerGroupName
	 * @param triggerExp 触发器表达式
	 */
	public static void addTrigger(String triggerName, String triggerGroupName,String triggerExp ){
		try {
			Scheduler sched = gSchedulerFactory.getScheduler();			
			CronTrigger trigger = new CronTrigger(triggerName, triggerGroupName);// 触发器名,触发器组
			trigger.setCronExpression(triggerExp);
			sched.scheduleJob(trigger);
		} catch (Exception e) {			
			e.printStackTrace();
		}
		
	}
	
	/****
	 * 获得单个job详细信息 JobDetail
	 * @param jobName 任务名
	 * @param jobGroup 任务组
	 * @return JobDetail job详细信息
	 */
	public static JobDetail getSingleJobInfo(String jobName, String jobGroup){
		
			JobDetail jobdetail=null;
		try {		
			Scheduler sched = gSchedulerFactory.getScheduler();			
			jobdetail=sched.getJobDetail(jobName, jobGroup);
		} catch (Exception e) {
			e.printStackTrace();
		}
			return jobdetail;
	}
	
	/****
	 * 移除单一job任务
	 * @param jobName
	 * @param jobGroupName
	 * @param triggerName
	 * @param triggerGroupName
	 */
	public static void removeSingleJob(String jobName) {
		try {
			Scheduler sched = gSchedulerFactory.getScheduler();
			sched.pauseTrigger("TRIGGER_NAME"+jobName, JobManager.JOB_GROUP);// 停止触发器
			sched.unscheduleJob("TRIGGER_NAME"+jobName,JobManager.JOB_GROUP);// 移除触发器
			sched.deleteJob(jobName, JobManager.JOB_GROUP);// 删除任务
			logger.info("移除"+jobName+"job成功");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	/****
	 * 暂停单一任务job 
	 * @param jobName
	 * @param groupName
	 */
	public static void pauseSingleJob(String jobName){
		try {		
			Scheduler sched = gSchedulerFactory.getScheduler();			
			sched.pauseJob(jobName, JobManager.JOB_GROUP);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
	/****
	 * 恢复单一任务job 
	 * @param jobName
	 * @param groupName
	 */
	public static void resumeSingleJob(String jobName){
		try {		
			Scheduler sched = gSchedulerFactory.getScheduler();			
			sched.resumeJob(jobName, JobManager.JOB_GROUP);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}	

	/****
	 * 立即执行一个任务
	 * @param jobName
	 * @param groupName
	 */
	public static boolean immediatelyExecuteSingleJob(String jobName, String groupName,Map<String,Object> paramMap ){
		boolean result = false;

		try {		
			Scheduler sched = gSchedulerFactory.getScheduler();
			JobDataMap jobdatamap=new JobDataMap();
			jobdatamap.put("immediaSingleJobparam", paramMap);
			sched.triggerJobWithVolatileTrigger(jobName, groupName, jobdatamap);
			if (!sched.isShutdown()) {
				sched.start();
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
	
	/****
	 * 启动Scheduler
	 */
	public static void laughScheduler() {  
		try {  
			Scheduler sched = gSchedulerFactory.getScheduler();  
			if (sched.isShutdown()) {  
				sched.start();  
			}  
		} catch (Exception e) {  
			throw new RuntimeException(e);  
		}  
	}
	
	/*****
	* 
	* @param JOB_METHOD_NAME
	* @param JOB_CLASS_NAME
	* @param paramMap 业务方法的参数
	* @param listener 传this对象
	* @throws InvocationTargetException
	* @throws IllegalAccessException
	* @throws IllegalArgumentException
	* @throws NoSuchMethodException
	* @throws SecurityException
	*/	
	public  static void startBusinessMethod (String JOB_METHOD_NAME,String JOB_CLASS_NAME, Map<String ,Object> paramMap, IScheduleJobListener listener) throws InvocationTargetException,IllegalAccessException,IllegalArgumentException,NoSuchMethodException, SecurityException{
		//IScheduleJobListener listener 必须用接口进行接收。实现类JobWrapper,和Class<T>都不可以。
		ApplicationContext context = ScheduleMethodInvokingJobDetailFactoryBean.getApplicationContext();
		Object obj = context.getBean(JOB_CLASS_NAME);
		if(obj!=null){
			Class<?> cls = obj.getClass();
			Method m= cls.getDeclaredMethod(JOB_METHOD_NAME, Map.class, IScheduleJobListener.class);
			if(m!=null){
				m.invoke(obj, paramMap, listener);
				
			}
		}
	}
	/**
	*public Method[] getMethods()返回某个类的所有公用(public)方法包括其继承类的公用方法,当然也包括它所实现接口的方法。
	*public Method[] getDeclaredMethods()对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。当然也包括它所实现接口的方法。
	**/
	
}


JobWrapper单任务管理类,实现了job接口。在execute方法中通过sping拿到对象,然后通过反射调用业务类的方法。

同时传递业务参数,和调用类的对象,以便业务类进行完业务处理方法后可以回调方法onJobDone()修改任务状态。

package com.schedule.framework;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;

import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.context.ApplicationContext;
import org.apache.log4j.Logger;

import com.schedule.framework.util.JdbcTool;
import com.schedule.framework.util.ScheduleMethodInvokingJobDetailFactoryBean;
public class JobWrapper implements Job, IScheduleJobListener{

	private static final Logger log=Logger.getLogger(JobWrapper.class);
	
	@Override
	public void execute(JobExecutionContext jobcontext) throws JobExecutionException {
		
		//获得重跑的单任务参数
		JobDataMap dataMap = jobcontext.getMergedJobDataMap();
		Map<String,Object> immediaSingleJobparam=(Map<String,Object>) dataMap.get("immediaSingleJobparam");
		
		
		//获得单任务的job_name job_group
		JobDetail jobDetail = jobcontext.getJobDetail();
		String job_name = jobDetail.getName();
		String job_group = jobDetail.getGroup();
		 
		//获得单任务包路径和入口
		Map<String,String> paramMap= this.querySchedulejob(job_name, job_group);
		String JOB_METHOD_NAME=paramMap.get("JOB_METHOD_NAME");
		String JOB_CLASS_NAME=paramMap.get("JOB_CLASS_NAME");

		try {
			
			JobManager.startBusinessMethod(JOB_METHOD_NAME, JOB_CLASS_NAME, immediaSingleJobparam, this);
			
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 只有在业务回调此方法的时候,表明该任务完成!
	 */
	@Override
	public void onJobDone(String stateFlag, String message) {
		// TODO Auto-generated method stub
		log.info("onJobDone: "+stateFlag+" - "+message);
		
	}

	@Override
	public void updateJobProcess(float processing) {
		// TODO Auto-generated method stub
		
	}

	
	private static Map<String,String> querySchedulejob(String job_name,String job_group ){
		
		Map<String,String> paramMap=new HashMap<String,String>();
		
		String sql="SELECT * FROM SCHEDULE_JOB WHERE 1=1 AND job_name='"+job_name+"'and job_group='"+job_group+"'";
		Connection conn=JdbcTool.getConnByJdbc();
		PreparedStatement ps;
		ResultSet rs=null;
		try {
			ps = conn.prepareStatement(sql);
			rs=ps.executeQuery();
			while(rs.next()){
				String JOB_CLASS_NAME=rs.getString("job_class_name");
				String JOB_METHOD_NAME=rs.getString("JOB_METHOD_NAME");
				paramMap.put("JOB_CLASS_NAME", JOB_CLASS_NAME);
				paramMap.put("JOB_METHOD_NAME", JOB_METHOD_NAME);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} 
		return paramMap;
	}
	
}
//业务类

package com.biz.service.impl;

import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.schedule.framework.IScheduleJobListener;

/**
 *业务类,由spring管理
 * 
 */
@Component("testquartzServiceImpl")
public class TestquartzServiceImpl implements TestquartzService {

	public static Log log = LogFactory.getLog(TestquartzServiceImpl.class);

	@Autowired
	private ServiceA ServiceAImpl;


	{
		System.out.println("/*****************************/");
		System.out.println("/*********spring创建TestquartzServiceImpl*******/");
		System.out.println("/*****************************/");
	}

	@Override
	public void TestHelloWorld(Map<String, Object> params,IScheduleJobListener listener) {
		//回调方法
		listener.onJobDone("1", "runtime excpetion!");
		
	}
	
	
}

执行业务方法后,提供回调方法
package com.schedule.framework;

public interface IScheduleJobListener {

	/**
	 * call back when job has done.
	 * 业务回调方法,表明业务处理完成
	 * 
	 * @param flag 取值: 
	 * @param message log-message
	 */
	public void onJobDone(String stateFlag, String message);
	
	public void updateJobProcess(float processing);
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值