@
- 前言
- 一、先图解一下本次文件内容
- 二、放代码....
- 三、测试代码
- 0、创建定时任务
- 1、定时任务自动停止
- 2、定时任务中参数改变策略
- 后言
前言
在很多刚使用quartz的小伙伴的体验中,如果说没有碰到这个问题的话,那可能就是还没有往深入的走,也或许有其他的解决方案。
然后wangwang我呢,也找了很久的资料才找到的。然后跟自己的项目需求相结合就成了这个亚子。
后面会放参考博客内容的:(本次为简单参考为主,不做过多讲解)
一、先图解一下本次文件内容
二、放代码....
MyJobFactory.java
package com.bj.quartz.config;
import groovy.util.logging.Slf4j;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
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.Component;
@Component
@Slf4j
public class MyJobFactory extends SpringBeanJobFactory
implements ApplicationContextAware {
@Autowired
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;
}
}
QuartzConfiguration.java
package com.bj.quartz.config;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
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 QuartzConfiguration {
@Autowired
private MyJobFactory myJobFactory;
//创建调度器工厂
@Bean(name = "SchedulerFactory")
public SchedulerFactoryBean schedulerFactoryBean(){
SchedulerFactoryBean factoryBean=new SchedulerFactoryBean();
factoryBean.setJobFactory(myJobFactory);
return factoryBean;
}
@Bean(name="scheduler")
public Scheduler scheduler(){
return schedulerFactoryBean().getScheduler();
}
}
配置完这些之后,其实就可以了,你就可以通过控制scheduler去生成jobDetail,trigger之类的。并且不用担心spring管理的容器无法注入进来的问题
可能有些人说,这么就这么一点点呢,当然咯quartz的内容往往不止这一些,还有一些持久化的策略之类的,甚至可以提供搭建一个定时任务的控制平台。只不过暂时我这个就只有这些,能开机就使用的定时任务。
接下来的就是我本次需求的两个重点测试:1、定时任务自动停止,2、定时任务中参数改变策略
不需要的小伙伴也可以不看。。。。
三、测试代码
0、创建定时任务
initQuartz.java
这个是写的一个自启动的时候就编译一个定时任务规则的类
package com.bj.quartz.init;
import com.bj.quartz.service.TScheduleTriggerParamService;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
@Component
public class initQuartz implements ApplicationRunner {
//job1的定时任务
@Value("${jobName1}")
private String jobName;
@Value("${groupName1}")
private String groupName;
@Value("${cron1}")
private String cron;
//job2的定时任务
@Value("${jobName2}")
private String jobName2;
@Value("${groupName2}")
private String groupName2;
@Value("${cron2}")
private String cron2;
@Autowired
private Scheduler scheduler;
private static final Logger logger = LoggerFactory.getLogger(initQuartz.class);
@Override
public void run(ApplicationArguments applicationArguments) throws Exception {
logger.info("================quartz启动成功==============");
//创建job1
addQuartz(jobName,groupName,cron);
//创建job2
addQuartz(jobName2,groupName2,cron2);
}
public void addQuartz(String jobName, String jobGroup, String cron){
try {
//JobName+JobGroup=Primary Key
//根据jobName和jobGroup生成TriggerKey
TriggerKey triggerKey =
TriggerKey.triggerKey(jobName, jobGroup);
//根据TriggerKey到Scheduler调度器中获取触发器
CronTrigger cronTrigger = (CronTrigger)
scheduler.getTrigger(triggerKey);
System.out.println("创建调度器");
//创建任务详情
JobDetail jobDetail=
JobBuilder.newJob((Class extends Job>) Class.forName(jobName))
.withIdentity(jobName,jobGroup)
.build();
//往Job任务中传递参数
JobDataMap jobDataMap = jobDetail.getJobDataMap();
//创建表达式调度器
CronScheduleBuilder cronSchedule =
CronScheduleBuilder.cronSchedule(cron);
//创建Trigger
cronTrigger= TriggerBuilder.newTrigger()
.withIdentity(jobName, jobGroup)
.withSchedule(cronSchedule)
.build();
//将jobDetail和Trigger注入到scheduler调度器中
scheduler.scheduleJob(jobDetail,cronTrigger);
}catch (Exception e){
e.printStackTrace();
}
}
}
1、定时任务自动停止
任务类
Myjob1.java
package com.bj.quartz.job;
import com.bj.util.ControllerUtil;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component
public class Myjob1 implements Job {
@Value("${jobName1}")
private String jobName;
@Value("${groupName1}")
private String groupName;
@Value("${cron1}")
private String cron;
@Autowired
private Scheduler scheduler;
@Override
public void execute(JobExecutionContext jobExecutionContext) {
//任务主体
taskBody(jobExecutionContext);
}
/**
* 任务主体
*/
private void taskBody(JobExecutionContext jobExecutionContext){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//获取任务详情中的dataMap集合
JobDetail jobDetail = jobExecutionContext.getJobDetail();
JobDataMap jobDataMap = jobDetail.getJobDataMap();
System.out.println("这是我的myjob1111111定时任务"+sdf.format(new Date()));
System.out.println("本方法的一个参数有:"+jobDataMap.size());
System.out.println("job:"+jobDataMap.get("job")+"level"+jobDataMap.get("level"));
System.out.println("-------------------------------");
String BockStartTime = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
long timeSize=0;
try {
/*
* 拿当前时间和规定时间相比较
* */
timeSize = this.compareTime2(BockStartTime, "20200402172430");
} catch (ParseException e) {
e.printStackTrace();
}
/*
* 如果大于0则代表任务该停下来
* */
if(timeSize>0){
System.err.println("stop job 任务!!!");
//调用停止定时任务的方法
this.stopQuary(jobName,groupName);
}
}
/**
* 关闭quary定时任务
*/
private void stopQuary(String jobName, String groupName){
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, groupName);
try {
/*
*停止触发器
* */
scheduler.pauseTrigger(triggerKey);
/*
*移除触发器
* */
scheduler.unscheduleJob(triggerKey);
scheduler.deleteJob(JobKey.jobKey(jobName, groupName));
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* TODO 取两个时间的差
* @param day1
* @param day2
* @return 秒
* @throws ParseException
*/
public long compareTime2(String day1, String day2)
throws ParseException {
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
Date rjsj = df.parse(day1);
Date dksj = df.parse(day2);
long stateTimeLong = rjsj.getTime();
long endTimeLong = dksj.getTime();
long day = (stateTimeLong - endTimeLong) / 1000L;
return day;
}
}
2、定时任务中参数改变策略
Myjob2.java
package com.bj.quartz.job;
import com.bj.entity.TScheduleTriggerParam;
import com.bj.quartz.service.TScheduleTriggerParamService;
import com.bj.quartz.util.paramMap;
import groovy.util.logging.Slf4j;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@Component
@Slf4j
public class Myjob2 implements Job {
@Autowired
private TScheduleTriggerParamService tScheduleTriggerParamService;
@Override
public void execute(JobExecutionContext jobExecutionContext) {
//任务主体
taskBody(jobExecutionContext);
}
private void taskBody(JobExecutionContext jobExecutionContext){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//获取任务详情中的dataMap集合
JobDetail jobDetail = jobExecutionContext.getJobDetail();
JobDataMap jobDataMap = jobDetail.getJobDataMap();
//更新params里面的值
List params =
tScheduleTriggerParamService.queryScheduleParamLst(1);
for (TScheduleTriggerParam param : params) {
jobDataMap.put(param.getName(),param.getValue());
}
System.err.println("这是我的myjob定时任务"+sdf.format(new Date()));
System.err.println("本方法的一个参数有:"+jobDataMap.size());
System.err.println("name:"+jobDataMap.get("name")+"score"+jobDataMap.get("score"));
System.out.println("-------------------------------");
//我自己提供的一个Map值
HashMap jobMap1 = paramMap.getJobMap1();
System.out.println("自己建的map:"+jobMap1.get("hh"));
}
}
这个我就得唠唠嗑了,参数的设置可能有三种方式:
1、使用一个静态常量的map类,然后每次调用修改参数的service的时候同时把map类中的数据重新替换掉,
2、使用redis进行存储,如果是多集群的话,
3、每次使用job任务的时候都到数据库去查询一下参数并且更替掉。
根据自身情况来吧。。
后言
不过说实话,如果是需要深入了解的还是得看看官方文档之类的。
像w3c中的quartz。
还有我看到的比较详细的:触发器介绍
本次参考后解决问题的博客:Springboot整合quartz框架(附代码)
我是wangwang,感谢能看到这里。
欢迎在评论区进行评论。