第一步我们将需要的jar引入到项目中
<dependency>
<groupId>org.quartz-schedulergroupId>
<artifactId>quartzartifactId>
<version>2.3.0version>
dependency>
<dependency>
<groupId>org.quartz-schedulergroupId>
<artifactId>quartz-jobsartifactId>
<version>2.3.0version>
dependency>
quartz 数据库持久化需要用到11张表。我们需要在数据库中执行mysql的初始化脚本。
mysql 初始化脚本下载
#============================================================================
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName=quartzScheduler
#ID设置为自动获取 每一个必须不同
org.quartz.scheduler.instanceId = AUTO
#远程管理相关的配置,全部关闭
org.quartz.scheduler.rmi.export= false
org.quartz.scheduler.rmi.proxy= false
org.quartz.scheduler.wrapJobExecutionInUserTransaction=false
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
#线程数量
org.quartz.threadPool.threadCount=15
#线程优先级
org.quartz.threadPool.threadPriority=5
#自创建父线程
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true
#容许的最大作业延
org.quartz.jobStore.misfireThreshold= 60000
#持久化配置
#数据保存方式为持久化
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties=true
#加入集群
org.quartz.jobStore.isClustered = false
#数据库表前缀
org.quartz.jobStore.tablePrefix=QRTZ_
#调度实例失效的检查时间间隔
org.quartz.jobStore.clusterCheckinInterval = 20000
# jobStore处理未按时触发的Job的数量
org.quartz.jobStore.maxMisfiresToHandleAtATime=20
@Configuration
@Data
public class QuartzConfig {
public static final String QUARTZ_PROPERTIES_PATH = "/quartz.properties";
@Resource
private DataSource dataSource;
@Resource
private PlatformTransactionManager transactionManager;
@Resource
private ApplicationContext applicationContext;
@Bean(name = "jobFactory")
public JobFactory jobFactory(ApplicationContext applicationContext) {
AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
jobFactory.setApplicationContext(applicationContext);
return jobFactory;
}
@Bean (name = "schedulerFactoryBean")
public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setJobFactory(jobFactory(applicationContext));
factory.setQuartzProperties(quartzProperties());
factory.setOverwriteExistingJobs(true); //每次启动都更新job信息
factory.setDataSource(dataSource);//jdbc store
factory.setStartupDelay(30);// QuartzScheduler 延时启动,应用启动完30秒后 QuartzScheduler 再启动
factory.setAutoStartup(true);
factory.setTransactionManager(transactionManager);
return factory;
}
/**
* quartz 初始化监听器
* @return
*/
@Bean
public QuartzInitializerListener initializerListener(){
return new QuartzInitializerListener();
}
@Bean
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource(QUARTZ_PROPERTIES_PATH));
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
/**
* 通过SchedulerFactoryBean获取Scheduler的实例
*/
public static 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;
}
}
}
public class SayHelloJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext)
throws JobExecutionException {
//todo
System.out.println("Hello word!");
}
}
@Controller
@RequestMapping("/quartz")
public class InitQuartzController {
@Autowired
private SchedulerFactoryBean schedulerFactoryBean;
private static final String TRIGGER_GROUP_NAME="group1";
private static final String JOB_GROUP_NAME="group1";
/**
* 初始化定时任务
*/
@RequestMapping("/init")
@ResponseBody
@Authorization
public String scheduleJobs() throws SchedulerException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobDetail jobDetail = JobBuilder.newJob(SayHelloJob.class)
.withDescription("sayHello定时任务")
.withIdentity("SayHelloJob", JOB_GROUP_NAME)
.build();
Trigger trigger = TriggerBuilder.newTrigger()
.forJob(jobDetail)
.withSchedule(cronSchedule("0 10 7 * * ?"))
.build();
if(!scheduler.checkExists(JobKey.jobKey("AddArticleReadRecordJob","group1"))){
scheduler.scheduleJob(jobDetail,trigger);
}
scheduler.start();
return "add success";
}
/**
*
* @param jobJava
* @param jobDesc
* @param jobName
* @param group
* @param cron
* @return
*/
@RequestMapping("/add")
@ResponseBody
@Authorization //权限验证,非必须
public String addJob(String jobJava,String jobDesc,String jobName, @RequestParam(name = "group",defaultValue = "group1")String group,
@RequestParam(name = "cron") String cron) throws SchedulerException, ClassNotFoundException {
Class jobClass=Class.forName(jobJava);
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobDetail jobDetail = JobBuilder.newJob(jobClass)
.withDescription(jobDesc)
.withIdentity(jobName, group)
.build();
Trigger trigger = TriggerBuilder.newTrigger()
.forJob(jobDetail)
.withSchedule(cronSchedule(cron))
.build();
if(!scheduler.checkExists(JobKey.jobKey(jobName,group))){
scheduler.scheduleJob(jobDetail,trigger);
}
scheduler.start();
return "添加成功";
}
@RequestMapping(value = "/resumeJob",method = RequestMethod.GET)
@ResponseBody
@Authorization
public String resumeJob(String jobName, String jobGroup) throws SchedulerException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey=JobKey.jobKey(jobName,jobGroup);
List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
//将trigger表中的state重置
triggers.forEach(x->{
try {
scheduler.resetTriggerFromErrorState(x.getKey());
} catch (SchedulerException e) {
Logs.error("重置定时任务异常:"+e.getMessage(),e);
}
});
scheduler.resumeJob(jobKey);
return "success";
}
/**
* 删除一个定时任务
* @return
*/
@ResponseBody
@RequestMapping("/removeJob")
@Authorization
public String removeJob(String jobName,String jobGroupName) throws SchedulerException {
Scheduler scheduler=schedulerFactoryBean.getScheduler();
TriggerKey tiger= new TriggerKey(jobName,TRIGGER_GROUP_NAME);
scheduler.pauseTrigger(tiger);
scheduler.unscheduleJob(tiger);
scheduler.deleteJob(new JobKey(jobName,jobGroupName));
return "success";
}
/**
* 修改定时任务执行时间表达式
* @param jobName
* @param jobGroupName
* @param triggerName
* @param triggerGroupName
* @param cron
* @return
*/
@ResponseBody
@RequestMapping("/modifyJob")
@Authorization
public String modifyJob(String jobName,String jobGroupName,String triggerName,String triggerGroupName,String cron){
try {
Logs.info("jobName="+jobName+"; jobGroupName="+jobGroupName+"; triggerName="+triggerName+"; triggerGroupName="+triggerGroupName+"; cron="+cron);
TriggerKey triggerKey =null;
Scheduler scheduler = schedulerFactoryBean.getScheduler();
if(StringUtils.hasText(triggerName)||StringUtils.hasText(triggerGroupName)){
triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
}else {
//通过任务名称和任务主修改
List<? extends Trigger>triggers= scheduler.getTriggersOfJob(JobKey.jobKey(jobName,jobGroupName));
if(triggers!=null&&triggers.size()>0){
triggerKey=triggers.get(0).getKey();
}
}
Logs.info("triggerName= "+triggerKey.getName()+"; triggerGroupName="+triggerKey.getGroup());
CronTrigger cronTrigger= (CronTrigger) scheduler.getTrigger(triggerKey);
if(cronTrigger==null){
return "定时任务出发时间为空!更新失败";
}
String oldTime=cronTrigger.getCronExpression();
if(!oldTime.equals(cron)){//判断表达式是否一致,如果一致则不需要修改
TriggerBuilder<Trigger> triggerBuilder=TriggerBuilder.newTrigger();
triggerBuilder.withIdentity(triggerKey.getName(),triggerKey.getGroup());
triggerBuilder.startNow();
//触发器设定
triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
// 创建Trigger对象
cronTrigger = (CronTrigger) triggerBuilder.build();
scheduler.resumeTrigger(triggerKey);
scheduler.rescheduleJob(triggerKey,cronTrigger);
}
}catch (Exception e){
Logs.error("修改定时任务异常:"+e.getMessage(),e);
return "failed";
}
return "success";
}
}