之前业务的定时任务在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);
}