首先我要记录两种quartz集成的方式
第一种是只有一个任务,定时执行即可,不需要动态管理
第二种是通过程序去控制定时任务的管理
不管哪种,首先导入依赖
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.3</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
然后第一种很简单
首先创建配置类
package com.hqjl.classcard.quartz;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
/**
* @author chunying
* @Date: 2018/11/13 0013
*/
public class WechatConfiguration {
@Bean(name = "detailFactoryBean_")
//参数是执行定时任务的类
public MethodInvokingJobDetailFactoryBean detailFactoryBean(AddSendMessageConfig wechatQuartz) {
MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
//对应job对象
bean.setTargetObject(wechatQuartz);
//设置对应执行方法
bean.setTargetMethod("refresh");
bean.setConcurrent(false);
return bean;
}
@Bean(name = "cronTriggerBean_")
public CronTriggerFactoryBean cronTriggerBean(MethodInvokingJobDetailFactoryBean detailFactoryBean_){
CronTriggerFactoryBean trigger = new CronTriggerFactoryBean ();
trigger.setJobDetail(detailFactoryBean_.getObject());
try {
trigger.setCronExpression("0 0 2 * * ?");
// trigger.setCronExpression ("0/5 * * ? * *");//每5秒执行一次
}catch(Exception e) {
throw new RuntimeException("定时刷新数据出错----------------------------------------------" + e);
}
return trigger;
}
@Bean
public SchedulerFactoryBean schedulerFactory(CronTriggerFactoryBean cronTriggerBean_){
SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean ();
schedulerFactory.setTriggers(cronTriggerBean_.getObject());
return schedulerFactory;
}
}
这里有三个方法,
第一个配置MethodInvokingJobDetailFactoryBean 这里要传入我们job对象,也就是要执行任务的对象
第二个配置CronTriggerFactoryBean 这里要配置cron表达式 来控制job什么时候执行 传入上面的MethodInvokingJobDetailFactoryBean
第三个配置SchedulerFactoryBean 调度器传入我们上面配置的CronTriggerFactoryBean
这里的job对象我就不创建了 有一个AddSendMessageConfig对象 有一个refresh 方法就可以了 方法里面就是具体的需要执行的定时业务逻辑
第二种:
首先定义一个定时任务管理者
package com.hqjl.classcard.quartz;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
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.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* @author chunying
* @Date: 2018/11/12 0012
*/
@Component
@Scope("singleton")
public class QuartzManager implements ApplicationContextAware {
private static SchedulerFactory schedulerFactory = new StdSchedulerFactory();
private static final String JOB_DEFAULT_GROUP_NAME = "JOB_DEFAULT_GROUP_NAME";
private static final String TRIGGER_DEFAULT_GROUP_NAME = "TRIGGER_DEFAULT_GROUP_NAME";
private Log logger = LogFactory.getLog(QuartzManager.class);
private ApplicationContext applicationContext;
private static Scheduler scheduler;
static {
try {
scheduler = schedulerFactory.getScheduler();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
;
@Autowired
private AutowiringSpringBeanJobFactory autowiringSpringBeanJobFactory;
public void start() {
//启动所有任务
try {
scheduler.setJobFactory(autowiringSpringBeanJobFactory);
//启动所有任务,这里获取AbstractTask的所有子类
Map<String, AbsTractTask> tasks = applicationContext.getBeansOfType(AbsTractTask.class);
tasks.forEach((k, v) -> {
String cronExpression = v.getCronExpression();
if (cronExpression != null) {
addJob(k, v.getClass().getName(), cronExpression , new HashMap());
}
});
logger.info("start jobs finished.");
} catch (SchedulerException e) {
logger.error(e.getMessage(), e);
throw new RuntimeException("init Scheduler failed");
}
}
public boolean addJob(String jobName, String jobClass, String cronExp, Map data) {
boolean result = false;
if (!CronExpression.isValidExpression(cronExp)) {
return result;
}
try {
JobDetail jobDetail = JobBuilder.newJob().withIdentity(new JobKey(jobName, JOB_DEFAULT_GROUP_NAME))
.ofType((Class<Job>) Class.forName(jobClass))
.build();
//这里进行外部向job里面传递参数
JobDataMap jobDataMap = jobDetail.getJobDataMap();
jobDataMap.putAll(data);
Trigger trigger = TriggerBuilder.newTrigger()
.forJob(jobDetail)
.withSchedule(CronScheduleBuilder.cronSchedule(cronExp))
.withIdentity(new TriggerKey(jobName, TRIGGER_DEFAULT_GROUP_NAME))
.build();
scheduler.setJobFactory(autowiringSpringBeanJobFactory);
scheduler.scheduleJob(jobDetail, trigger);
scheduler.start();
} catch (Exception e) {
logger.error(e.getMessage(), e);
logger.error("QuartzManager add job failed");
}
return result;
}
public boolean updateJob(String jobName, String cronExp) {
boolean result = false;
if (!CronExpression.isValidExpression(cronExp)) {
return result;
}
JobKey jobKey = new JobKey(jobName, JOB_DEFAULT_GROUP_NAME);
TriggerKey triggerKey = new TriggerKey(jobName, TRIGGER_DEFAULT_GROUP_NAME);
try {
if (scheduler.checkExists(jobKey) && scheduler.checkExists(triggerKey)) {
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
Trigger newTrigger = TriggerBuilder.newTrigger()
.forJob(jobDetail)
.withSchedule(CronScheduleBuilder.cronSchedule(cronExp))
.withIdentity(new TriggerKey(jobName, TRIGGER_DEFAULT_GROUP_NAME))
.build();
scheduler.rescheduleJob(triggerKey, newTrigger);
result = true;
} else {
}
} catch (SchedulerException e) {
logger.error(e.getMessage(), e);
}
return result;
}
public boolean deleteJob(String jobName) {
boolean result = false;
JobKey jobKey = new JobKey(jobName, JOB_DEFAULT_GROUP_NAME);
try {
if (scheduler.checkExists(jobKey)) {
result = scheduler.deleteJob(jobKey);
} else {
}
} catch (SchedulerException e) {
logger.error(e.getMessage(), e);
}
return result;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
这里面用到了一个自定义的AutowiringSpringBeanJobFactory 说一下这个类,quartz在启动定时任务的时候,是自己新开启一个线程的,里面的对象是类似一个jobContext来管理的,所以如果job的具体实现需要用到我们的业务对象,会发现用spring注入为空,所以需要把quartz的job对象放到spring容器里进行管理。
package com.hqjl.classcard.quartz;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
import org.springframework.stereotype.Service;
/**
* @author chunying
* @Date: 2018/11/12 0012
*/
@Service
public class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory
implements ApplicationContextAware {
private transient AutowireCapableBeanFactory beanFactory;
@Override
public void setApplicationContext(final ApplicationContext context) {
beanFactory = context.getAutowireCapableBeanFactory();
}
@Override
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle);
beanFactory.autowireBean(job);
return job;
}
}
之后的就很简单的 定义一个抽象类实现job
package com.hqjl.classcard.quartz;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.springframework.stereotype.Component;
import java.text.ParseException;
/**
* @author chunying
* @Date: 2018/11/12 0012
*/
public abstract class AbsTractTask implements Job {
protected abstract void executeInternal(JobExecutionContext context) throws ParseException;
protected String cronExpression;
@Override
public void execute(JobExecutionContext context) {
try {
executeInternal(context);
} catch (Exception e) {
e.printStackTrace();
}
}
public String getCronExpression() {
return cronExpression;
}
}
我们定义的job对象来继承这个类
package com.hqjl.classcard.quartz;
import com.hqjl.classcard.bean.WechatData;
import com.hqjl.classcard.bean.WechatQuartzMessage;
import com.hqjl.classcard.bean.response.AdminClassCheck;
import com.hqjl.classcard.bean.response.ClassCheck;
import com.hqjl.classcard.bean.response.SettingBean;
import com.hqjl.classcard.dao.WechatQuartzMessageDao;
import com.hqjl.classcard.data.check.DataResultService;
import com.hqjl.classcard.data.check.SchoolData;
import com.hqjl.classcard.service.CheckingInfoService;
import com.hqjl.classcard.service.SettingService;
import com.hqjl.classcard.service.StudentInfoService;
import com.hqjl.classcard.utils.CronUtil;
import com.hqjl.classcard.utils.DateUtil;
import com.hqjl.common.framework.spring.SpringContextUtil;
import com.hqjl.scheduler.bean.classcard.*;
import com.hqjl.scheduler.classcard.IScheduleClassCardService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author chunying
*/
@Component
@Service
@DisallowConcurrentExecution
public class WechatQuartz extends AbsTractTask{
@Autowired
private SendThread sendThread;
@Autowired
private CheckingInfoService checkingInfoService;
@Autowired
private StudentInfoService studentInfoService;
@Autowired
private QuartzManager quartzManager;
@Autowired
private WechatMessageConfig wechatMessageConfig;
@Autowired
private WechatQuartzMessageDao wechatQuartzMessageDao;
@Autowired
private IScheduleClassCardService iScheduleClassCardService;
@Autowired
private SettingService settingService;
@Autowired
private DataResultService dataResultService;
public WechatQuartz(){};
private static final Log LOG = LogFactory.getLog(WechatQuartz.class);
//具体job实现
@Override
protected void executeInternal(JobExecutionContext context){
//这里可以拿到它进行job参数的传递 使用和map大体相同
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
}
}
本文介绍Quartz定时任务的两种集成方式:单一任务定时执行与程序动态管理。涵盖依赖导入、配置类创建、定时任务管理者定义及Job实现。
4151

被折叠的 条评论
为什么被折叠?



