引入jar
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.3</version>
</dependency>
建表
配置quartz.properties
# 固定前缀org.quartz
# 主要分为scheduler、threadPool、jobStore、plugin等部分
#实例名
org.quartz.scheduler.instanceName=Scheduler
#实例id(唯一,有缺省值)
org.quartz.scheduler.instanceId=SchedulerId
org.quartz.scheduler.rmi.export=false
org.quartz.scheduler.rmi.proxy=false
org.quartz.scheduler.wrapJobExecutionInUserTransaction=false
# 实例化ThreadPool时,使用的线程类为SimpleThreadPool
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
# 并发个数
org.quartz.threadPool.threadCount=5
# 优先级
org.quartz.threadPool.threadPriority=5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true
org.quartz.jobStore.misfireThreshold=5000
# 默认存储在内存中
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
import org.quartz.Scheduler;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import java.io.IOException;
import java.util.Properties;
@Configuration
public class SchedulerConfig {
@Bean
public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
schedulerFactoryBean.setQuartzProperties(quartzProperties());
return schedulerFactoryBean;
}
@Bean
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
//在quartz.properties中的属性被读取并注入后再初始化对象
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
/*
* quartz初始化监听器
*/
@Bean
public QuartzInitializerListener executorListener() {
return new QuartzInitializerListener();
}
/*
* 通过SchedulerFactoryBean获取Scheduler的实例
*/
@Bean(name="Scheduler")
public Scheduler scheduler() throws IOException {
return schedulerFactoryBean().getScheduler();
}
}
JobFactory
import com.alibaba.fastjson.JSONObject;
import com.inspur.ssp.supervise.bean.entity.SupJob;
import com.inspur.ssp.supervise.constant.Constant;
import org.apache.commons.lang.StringUtils;
import org.jangod.iweb.util.DaoFactory;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@DisallowConcurrentExecution
public class JobFactory implements Job{
private static Logger logger = LoggerFactory.getLogger(Constant.LOG_TYPE_JOB);
//默认执行入口
private static final String METHOD = "execute";
public JobFactory(){
}
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
SupJob jobBean = (SupJob)context.getMergedJobDataMap().get("scheduleJob");
long start = System.currentTimeMillis();
logger.info("定时任务【"+ jobBean.getName()+"】开始执行,执行时间:"+new Date());
String action = jobBean.getAction();
String method = jobBean.getMethod();
if(StringUtils.isEmpty(method)){
method = METHOD;
}
try {
Class clazz = DaoFactory.getClass(action);
Method[] methods = clazz.getMethods();//全部方法
for(Method _method : methods){
if(method.equals(_method.getName())){
Class<?>[] cls = _method.getParameterTypes();
if(cls.length == 0){
DaoFactory.invoke(action,method,cls,new Object[]{});
}else{
Map<String,Object> params = (Map<String,Object>)JSONObject.parse(jobBean.getParam());
if(null == params) {
params = new HashMap<>();
}
params.put("params",jobBean.getParam());
DaoFactory.invoke(action,method,cls,new Object[]{params});
}
}
}
} catch (Exception e) {
logger.error("执行定时任务【"+jobBean.getName()+"】出错,",e);
}finally {
long end = System.currentTimeMillis();
logger.info("定时任务【"+ jobBean.getName()+"】执行结束,耗时:"+((end-start)/1000)+"s");
}
}
}
任务初始化
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.inspur.ssp.supervise.bean.entity.SupJob;
import com.inspur.ssp.supervise.job.JobFactory;
import com.inspur.ssp.supervise.mapper.SupJobMapper;
import com.inspur.ssp.supervise.service.ISupJobService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@Transactional
public class SupJobServiceImpl extends ServiceImpl<SupJobMapper, SupJob> implements ISupJobService {
private static final String GROUP = "_group";
@Autowired @Qualifier("Scheduler")
private Scheduler scheduler;
@Override
public void initJob() throws Exception{
//获取任务列表
QueryWrapper<SupJob> queryWrapper= new QueryWrapper<SupJob>();
queryWrapper.eq("STATUS", "1");
List<SupJob> supJobs = this.baseMapper.selectList(queryWrapper);
for (SupJob jobBean : supJobs) {
//任务名称和任务组设置规格
String jobId = jobBean.getId();
String jobGroup=jobId+GROUP;
//触发器
TriggerKey triggerKey = TriggerKey.triggerKey(jobId, jobGroup);
CronTrigger trigger = (CronTrigger)scheduler.getTrigger(triggerKey);
//触发器不存在 则创建
if(trigger==null){
JobDetail jobDetail = JobBuilder.newJob(JobFactory.class).withIdentity(jobId, jobGroup).build();
jobDetail.getJobDataMap().put("scheduleJob",jobBean);
//表达式调度器构建
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(jobBean.getCron());
//按新的表达式构建一个新的触发器
trigger = TriggerBuilder.newTrigger().withIdentity(jobId, jobGroup).withSchedule(scheduleBuilder).build();
scheduler.scheduleJob(jobDetail,trigger);
}else{
//触发器已存在,则更新相应的定时设置
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(jobBean.getCron());
//按照新的表达式重新构建触发器
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
//按照新的触发器重新设置job执行
scheduler.rescheduleJob(triggerKey,trigger);
}
}
}
/**
* 获取job key
* @param jobId
* @return
*/
private JobKey getJobKey(String jobId) {
String jobGroup = jobId+GROUP;
return JobKey.jobKey(jobId,jobGroup);
}
@Override
public void deleteJob(String id)throws Exception{
JobKey jobKey = this.getJobKey(id);
scheduler.deleteJob(jobKey);
}
/**
* 新增任务
* @param supJob
* @throws Exception
*/
@Override
public void insertJob(SupJob supJob)throws Exception {
String jobId = supJob.getId();
String jobGroup = jobId+GROUP;
TriggerKey triggerKey = TriggerKey.triggerKey(jobId,jobGroup);
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
JobDetail jobDetail = JobBuilder.newJob(JobFactory.class).withIdentity(jobId,jobGroup).build();
jobDetail.getJobDataMap().put("scheduleJob", supJob);
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(supJob.getCron());
// 按新的表达式构建一个新的trigger
trigger = TriggerBuilder.newTrigger().withIdentity(jobId, jobGroup).withSchedule(scheduleBuilder).build();
scheduler.scheduleJob(jobDetail, trigger);
}
}
学习链接