Quartz定时任务简单实现

时间:2022-02-06 23:30:00

一、创建保存定时任务的table

bean_class为完全限定名,bean_name为实例化对象

Quartz定时任务简单实现

、创建JobInit类进行初始化工作

package com.mall.task.init;
import java.util.List;
import javax.annotation.Resource;
import org.apache.log4j.Logger;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdScheduler;
import com.mall.manager.service.ScheduleJobService;
import com.mall.untils.ScheduleJob;


@SuppressWarnings({"rawtypes","unchecked"})
public class JobInit {
Logger logger = Logger.getLogger(JobInit.class);

@Resource(name = "scheduler")
private StdScheduler scheduler;

@Resource
private ScheduleJobService scheduleJobService;


/**
* 初始化定时任务
* @throws Exception
*/
public void init() throws Exception {
List<ScheduleJob> jobList = scheduleJobService.findScheduleJob();
for (ScheduleJob job : jobList) {
deleteJob(job);// 删除任务
addJob(job);// 添加任务
}
}

/**
* 删除一个job

* @param scheduleJob
* @throws SchedulerException
*/
public void deleteJob(ScheduleJob scheduleJob) throws SchedulerException {

logger.info(scheduler + "***删除任务****key***" + (scheduleJob.getJobName() + scheduleJob.getJobGroup()));
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.deleteJob(jobKey);
}

/**
* 添加任务

* @param scheduleJob
* @throws SchedulerException
*/
public void addJob(ScheduleJob scheduleJob) throws SchedulerException {

if (scheduleJob == null || !(scheduleJob.getJobStatus())) {
return;
}

logger.info(scheduler + "***添加任务****key***" + (scheduleJob.getJobName() + scheduleJob.getJobGroup()));
TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

// 不存在,创建一个
if (null == trigger) {
Class clazz = scheduleJob.getIsConcurrent() == true ? QuartzJobFactory.class : QuartzJobFactoryExecution.class;
JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(scheduleJob.getJobName(), scheduleJob.getJobGroup()).build();
jobDetail.getJobDataMap().put("scheduleJob", scheduleJob);
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());
trigger = TriggerBuilder.newTrigger().withIdentity(scheduleJob.getJobName(), scheduleJob.getJobGroup()).withSchedule(scheduleBuilder).build();
scheduler.scheduleJob(jobDetail, trigger);
} else {
// Trigger已存在,那么更新相应的定时设置
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());
// 按新的cronExpression表达式重新构建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(triggerKey, trigger);
}
}
}


package com.mall.task.init;
import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import com.mall.untils.ScheduleJob;

/**
 * 
 * @Description: 计划任务执行处 无状态
 * @author tgy
 */
public class QuartzJobFactory implements Job {


public final Logger log = Logger.getLogger(QuartzJobFactory.class);

@Override
public void execute(JobExecutionContext context) throws JobExecutionException {

ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap().get("scheduleJob");
TaskUtils.invokMethod(scheduleJob);
}
}



package com.mall.task.init;

import org.apache.log4j.Logger;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import com.mall.untils.ScheduleJob;


@DisallowConcurrentExecution
public class QuartzJobFactoryExecution implements Job {

public final Logger log = Logger.getLogger(this.getClass());

@Override
public void execute(JobExecutionContext context) throws JobExecutionException {


ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap().get("scheduleJob");
TaskUtils.invokMethod(scheduleJob);


}
}




package com.mall.task.init;

import java.util.Locale;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;


public class SpringBeanUtil implements ApplicationContextAware {

private static ApplicationContext context;

@SuppressWarnings("static-access")
public void setApplicationContext(ApplicationContext contex) throws BeansException {

this.context = contex;
}

public static Object getBean(String beanName) {

return context.getBean(beanName);
}

public static String getMessage(String key) {

return context.getMessage(key, null, Locale.getDefault());
}
}




package com.mall.task.init;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import com.mall.untils.ScheduleJob;


@SuppressWarnings({ "rawtypes", "unchecked" })
public class TaskUtils {

public final static Logger log = Logger.getLogger(TaskUtils.class);

/**
* 通过反射调用scheduleJob中定义的方法

* @param scheduleJob
*/
public static void invokMethod(ScheduleJob scheduleJob) {

Object object = null;
Class clazz = null;
// BeanName不为空先按BeanName查找bean
if (StringUtils.isNotBlank(scheduleJob.getBeanName())) {
object = SpringBeanUtil.getBean(scheduleJob.getBeanName());
} else if (StringUtils.isNotBlank(scheduleJob.getBeanClass())) {
try {
clazz = Class.forName(scheduleJob.getBeanClass());
object = clazz.newInstance();
} catch (Exception e) {
log.debug("获取类对象出错:" + e.getMessage());
}
}
if (object == null) {
log.error("任务名称 = [" + scheduleJob.getJobName() + "]---------------未启动成功,请检查是否配置正确!!!");
return;
}
clazz = object.getClass();
Method method = null;
try {
method = clazz.getDeclaredMethod(scheduleJob.getMethodName());
} catch (NoSuchMethodException e) {
log.debug("任务名称 = [" + scheduleJob.getJobName() + "]---------------未启动成功,方法名设置错误!!!");
} catch (SecurityException e) {
log.debug("获取类对象出错:" + e.getMessage());
}
if (method != null) {
try {
method.invoke(object);
} catch (IllegalAccessException e) {
log.debug("调用反射对象出错:" + e.getMessage());
} catch (IllegalArgumentException e) {
log.debug("调用反射对象出错:" + e.getMessage());
} catch (InvocationTargetException e) {
log.debug("调用反射对象出错:" + e.getMessage());
}
}
}
}


package com.mall.untils;

import java.io.Serializable;
import java.sql.Timestamp;


/**
 * 定时器类
 * @author tgy
 *
 */
public class ScheduleJob implements Serializable{

/**

*/
private static final long serialVersionUID = 1L;
public Integer id;
/**
* 任务名称(必须)
*/
public String jobName;

/**
* 任务分组(非必须)
*/
public String jobGroup;

/**
* 任务状态 是否启动任务(必须)
*/
public Boolean jobStatus;

/**
* cron表达式(必须)
*/
public String cronExpression;

/**
* 描述(非必须)
*/
public String description;

/**
* 任务执行时调用哪个类的方法 包名+类名(必须)
*/
public String beanClass;

/**
* 任务是否有状态(必须)
*/
public Boolean isConcurrent;

/**
* spring bean(必须)
*/
public String beanName;

/**
* 任务调用的方法名(必须)
*/
public String methodName;

/**
* 创建时间
*/
public Timestamp createTime;

/**
* 更新时间
*/
public Timestamp updateTime;

}


三、配置springmvc加载bean

1).以下bean需配置在*.xml中

    <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" />
<bean id="springBeanUtil" class="com.mall.task.init.SpringBeanUtil" /> 
<bean id="jobInit" class="com.mall.task.init.JobInit" init-method="init"/>