Quartz定时任务封装
一般的系统都会有一些定时任务,那么我们将这个定时任务封装起来,只要系统需要添加定时任务时,只需调用此方法传入所需要的值即可完成定时任务。 自己自学整理的一些随笔
1.首先对周期粒度进行封装
public enum GranularityPeriod{
UNSPECIFIED(0), ONE_MIN(1), TWO_MINS(2), THREE_MINS(3), FOUR_MINS(4), FIVE_MINS(5), SIX_MINS(6), TEN_MINS(10), TWELVE_MINS(
12), FIFTEEN_MINS(15), TWENTY_MINS(20), THIRTY_MINS(30), ONE_HOUR(60), TWO_HOURS(120), THREE_HOURS(180), FOUR_HOURS(
240), SIX_HOURS(360), EIGHT_HOURS(480), TWELVE_HOURS(720), TWENTY_FOUR_HOURS(1440);
private final int value; GranularityPeriod(int value) {
this.value = value;
} public int value() {
return this.value;
} public static GranularityPeriod getGranularityPeriod(int value) { switch (value) {
case 0:
return UNSPECIFIED;
case 1:
return ONE_MIN;
case 2:
return TWO_MINS;
case 3:
return THREE_MINS;
case 4:
return FOUR_MINS;
case 5:
return FIVE_MINS;
case 6:
return SIX_MINS;
case 10:
return TEN_MINS;
case 12:
return TWELVE_MINS;
case 15:
return FIFTEEN_MINS;
case 20:
return TWENTY_MINS;
case 30:
return THIRTY_MINS;
case 60:
return ONE_HOUR;
case 120:
return TWO_HOURS;
case 180:
return THREE_HOURS;
case 240:
return FOUR_HOURS;
case 360:
return SIX_HOURS;
case 480:
return EIGHT_HOURS;
case 720:
return TWELVE_HOURS;
case 1440:
return TWENTY_FOUR_HOURS;
}
throw new IllegalArgumentException("NOT GranularityPeriod matched the argument!");
} }
2.对同步方式进行封装
public enum DateCycle {
BY_DAY, BY_WEEK, BY_MONTH;
}
public class DayOfWeek {
public static String getDay(int i) { switch (i) {
case 0:
return "Sun";
case 1:
return "Mon";
case 2:
return "Tue";
case 3:
return "Wed";
case 4:
return "Thu";
case 5:
return "Fri";
case 6:
return "Sat";
}
throw new IllegalArgumentException("NOT day matched the argument!");
}
}
3.设置需要定时同步的周期对象
(1)同步任务的任务名 跟 任务组名进行封装
public class JobInfo {
private String jobName;
private String jobGroupName; public JobInfo(String jobName,String jobGroupName){
this.jobName = jobName;
this.jobGroupName = jobGroupName;
}
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public String getJobGroupName() {
return jobGroupName;
}
public void setJobGroupName(String jobGroupName) {
this.jobGroupName = jobGroupName;
}
}
(2)定时任务的对象设定,并指定任务名 任务组名
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map; public class TimingSync implements Serializable {
private static final long serialVersionUID = 1L;
public static final Integer SWTICH_OFF =0;
public static final Integer BY_DAY =1;
public static final Integer BY_WEEK =2;
public static final Integer BY_MONTH =3;
public static final Integer TYPE_IOPS =0;
//public static final String IOPS_JOB_NAME ="my_sync";
//public static final String IOPS_JOB_GROUPNAME ="my_group";
/**
* 0--- 定时同步开关关闭
* 1--- 按天定时
* 2--- 按周定时
* 3--- 按月定时
*/
private Integer status;
private String day;//按月定时时填写该字段从1开始,第0位代表第一天,如1110101 代表某月的1号,2号,3号,5号,7号
private String week;//按周定时时填写该字段从周日开始一共7位0000000,如0100001 代表周一和周六
private Integer businessType;// 定时任务的业务类型,0代表my_sync,可以扩展其他业务
private String synctime = "00:00:00"; public final static Map<Integer,EbsJobInfo> JOB_TYPE_NAME_MAP = new HashMap<Integer,JobInfo>();
static {
JOB_TYPE_NAME_MAP.put(TYPE_MY, new EbsJobInfo("my_sync", "my_group"));
} public String getWeek() {
return week;
} public void setWeek(String week) {
this.week = week;
} public String getDay() {
return day;
} public void setDay(String day) {
this.day = day;
} public Integer getStatus() {
return status;
} public void setStatus(Integer status) {
this.status = status;
} public String getSynctime() {
return synctime;
} public void setSynctime(String synctime) {
this.synctime = synctime;
} @Override
public String toString() {
return "TimingSync [businessType="+businessType+", status=" + status + ", week=" + week + ", day=" + day + ", synctime=" + synctime + "]";
} public Integer getBusinessType() {
return businessType;
} public void setBusinessType(Integer businessType) {
this.businessType = businessType;
} }
4.封装调度机信息,用于存储所需要的同步周期方式
public class ScheduleInfo implements Serializable, Cloneable { private static final long serialVersionUID = 3258130271374160953L;
private String quartzName; private String quartzGroup;
private String executorId;
private Date startTime;
private Date endTime;
private Date tiggerTime;
private String weekDays, monthDays;
private DateCycle dateCycle = DateCycle.BY_DAY; public String getWeekDays() {
return weekDays;
} public void setWeekDays(String weekDays) {
this.weekDays = weekDays;
} public String getMonthDays() {
return monthDays;
} public void setMonthDays(String monthDays) {
this.monthDays = monthDays;
} public Date getEndTime() {
return endTime;
} public void setEndTime(Date endTime) {
this.endTime = endTime;
} public Date getStartTime() {
return startTime;
} public void setStartTime(Date startTime) {
this.startTime = startTime;
} public String getExecutorId() { return executorId;
} public void setExecutorId(String executorId) { this.executorId = executorId;
} public String getQuartzGroup() { return quartzGroup;
} public void setQuartzGroup(String quartzGroup) { this.quartzGroup = quartzGroup;
} public String getQuartzName() { return quartzName;
} public void setQuartzName(String quartzName) { this.quartzName = quartzName;
}
private GranularityPeriod granularityPeriod = GranularityPeriod.ONE_MIN; public static ScheduleInfo newInstance(Date startTime, Date stopTime) { ScheduleInfo schedule = new ScheduleInfo(); schedule.startTime = startTime;
schedule.endTime = stopTime; return schedule;
} public Date getTiggerTime() {
return tiggerTime;
} public void setTiggerTime(Date tiggerTime) {
this.tiggerTime = tiggerTime;
} public Object clone() throws CloneNotSupportedException {
ScheduleInfo clone = (ScheduleInfo) super.clone();
if(null == this.startTime){
clone.startTime = null;
}
else{
clone.startTime = (Date) this.startTime.clone();
}
if(null == this.endTime){
this.endTime = null;
}
else{
clone.endTime = (Date) this.endTime.clone();
}
return clone;
} public GranularityPeriod getGranularityPeriod() {
return granularityPeriod;
} public void setGranularityPeriod(GranularityPeriod granularityPeriod) {
this.granularityPeriod = granularityPeriod;
} public DateCycle getDateCycle() {
return dateCycle;
} public void setDateCycle(DateCycle dateCycle) {
this.dateCycle = dateCycle;
}
}
5.封装方法生成设定的所期望的同步规则
public class CronTriggerUtil {
// 所需要的符号
/**
* Comment for <code>SPACE</code>
*/
public final static String SPACE = " "; /**
* Comment for <code>ZERO</code>
*/
public final static String ZERO = "0"; /**
* Comment for <code>SUB</code>
*/
public final static String SUB = "-"; /**
* Comment for <code>DIV</code>
*/
public final static String DIV = "/"; /**
* Comment for <code>ASTERISK</code>
*/
public final static String ASTERISK = "*"; /**
* Comment for <code>INTERROGATION</code>
*/
public final static String INTERROGATION = "?"; /**
* Comment for <code>COMMA</code>
*/
public final static String COMMA = ","; /**
* 根据传入的自定义的定时方式生成trigger所认识的定时任务规则
*
*/
public String toCronExpr(ScheduleInfo schedule) {
String expr = toTimeCronExpr(schedule) + toDateCronExpr(schedule);
return expr;
} /**
* 获得时间表达式,分为3中情况处理,分别是:没有时间段,有一个时间段,有多个时间段,
*/
private String toTimeCronExpr(ScheduleInfo schedule) { StringBuilder result = new StringBuilder(); // 用开始时间作为启动时间
Date date = schedule.getStartTime();
Date currentDate = new Date(System.currentTimeMillis());
if(date == null){
date = currentDate;
}
int setSecond = getStartSeconds(date);
if(setSecond < 59){//59+1的话会导致开始时间大于触发时间,定时任务会延迟一个周期触发,所以这里去掉59s时的加1操作
setSecond = setSecond+1;
}
if(setSecond == 60){
setSecond = 0;
} result.append(setSecond).append(SPACE); // 特殊处理,在周期为天,判断tiggerTime。24小时
if(schedule.getGranularityPeriod().value() == 1440){
// date = new Date(date.getTime() + 1000 * 60 * 60);
result.append(getStartMinute(date)).append(SPACE).append(getStartHour(date)).append(SPACE); }
// 特殊处理,在周期为天,判断tiggerTime。12小时
else if(schedule.getGranularityPeriod().value() == 720){
// date = new Date(date.getTime() + 1000 * 60 * 60);
result.append(getStartMinute(date)).append(SPACE);
if(schedule.getEndTime() != null && schedule.getEndTime().getTime() - date.getTime() < 43200000){
result.append(getStartHour(date)).append(SPACE);
}
else{
result.append(getStartHour(date) + COMMA + getEndHour(date)).append(SPACE);
}
}
// 立即执行的情况
else if(schedule.getGranularityPeriod().value() == 0){
date = new Date(date.getTime() + 1000 * 60);
result.append(getStartMinute(date)).append(SPACE).append(getStartHour(date)).append(SPACE);
}
// 普通情况
else{
result.append(0).append(DIV).append(getValue(schedule.getGranularityPeriod())).append(SPACE)
.append(getHourTime(schedule)).append(SPACE);
} return result.toString();
} /**
* trigger time return start Seconds
*/
private int getStartSeconds(Date date) { Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(date.getTime());
return cal.get(Calendar.SECOND);
} /**
* trigger time return start miniute
*/
private int getStartMinute(Date date) { Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(date.getTime());
return cal.get(Calendar.MINUTE);
} /**
* trigger time return start hour
*/
private int getStartHour(Date date) { Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(date.getTime());
return cal.get(Calendar.HOUR_OF_DAY);
} /**
* 获得日期的月数
*/
private int getMonth(Date date) {
Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(date.getTime());
return cal.get(Calendar.MONTH) + 1;
} /**
* 获得日期的年数
*/
private int getYear(Date date) {
Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(date.getTime());
return cal.get(Calendar.YEAR);
} /**
* 获得日期的天数
*/
private int getDay(Date date) {
Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(date.getTime());
return cal.get(Calendar.DAY_OF_MONTH);
} /**
* 获取12小时的结束时间
*
* @param startHour
* @return
*/
private int getEndHour(Date date) {
Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(date.getTime());
int hour = cal.get(Calendar.HOUR_OF_DAY);
if(hour < 12){
return 12 + hour;
}
return (12 + hour) % 24;
} /**
* 得到循环周期为月的具体的号数,假如输入的是1,那么就加入他所在位置的号数
* exp: input = "111110001001" output= "1,2,3,4,5,9,12";
*/
private Object getByMonthDays(ScheduleInfo schedule) { String days = schedule.getMonthDays();
StringBuilder builder = new StringBuilder(); for (int i = 0; i < days.length(); i++){ if("1".equals(days.charAt(i) + "")){ builder.append(i + 1).append(COMMA);
}
}
String temp = builder.toString();
if(temp.endsWith(COMMA)){ return temp.substring(0, temp.length() - 1);
}
return temp;
} /**
* 得到循环周期为周的具体的星期天数, 例如输入的是1,
* 那么就加入他所在位置的星期数 exp: input = "0001000"; output= "Wed";
*/
public String getByWeekDays(ScheduleInfo schedule) { String days = schedule.getWeekDays();
StringBuilder builder = new StringBuilder(); for (int i = 0; i < days.length(); i++){ if("1".equals(days.charAt(i) + "")){ builder.append(DayOfWeek.getDay(i)).append(COMMA);
}
}
String temp = builder.toString();
if(temp.endsWith(COMMA)){ return temp.substring(0, temp.length() - 1);
}
return temp;
} private String toDateCronExpr(ScheduleInfo schedule) { StringBuilder result = new StringBuilder(); if(schedule.getGranularityPeriod().value() == 0){
Date date = schedule.getStartTime();
if(date == null)
date = new Date(System.currentTimeMillis());
result.append(getDay(date)).append(SPACE).append(getMonth(date)).append(SPACE).append(INTERROGATION)
.append(SPACE).append(getYear(date));
}
else if("BY_DAY".equals(schedule.getDateCycle().toString())){ result.append(ASTERISK).append(SPACE).append(ASTERISK).append(SPACE).append(INTERROGATION);
}
else if("BY_WEEK".equals(schedule.getDateCycle().toString())){ result.append(INTERROGATION).append(SPACE).append(ASTERISK).append(SPACE).append(getByWeekDays(schedule));
}
else if("BY_MONTH".equals(schedule.getDateCycle().toString())){ result.append(getByMonthDays(schedule)).append(SPACE).append(ASTERISK).append(SPACE).append(INTERROGATION);
} return result.toString();
} /**
* 由于跨多个小时quartz不认,最大只能以小时为单位,所以只能对其进行转换。
* 如:0 0/240 * * ? 想以每天为单位,每隔4个小时触发一次,但情况还是每个小时触发一次。 只有将其改为 0 0/60
* 0,4,8,12,16,20
*/
public String getHourTime(ScheduleInfo schedule) { int hourUnit = schedule.getGranularityPeriod().value(); String builder = null; if(hourUnit == 120){ builder = "0,2,4,6,8,10,12,14,16,18,20,22";
}
else if(hourUnit == 180){ builder = "0,3,6,9,12,15,18,21";
}
else if(hourUnit == 240){ builder = "0,4,8,12,16,20";
}
else if(hourUnit == 360){ builder = "0,6,12,18";
}
else if(hourUnit == 480){ builder = "0,8,16";
}
else if(hourUnit == 720){ builder = "0,12";
}else{ builder = "*";
}
return builder;
} /**
* 由于quartz的表达式最大支持为60分钟,因此,大于60就当作是60
*/
public String getValue(GranularityPeriod value) { if(value.value() > 60){ return "60";
} return value.value() + "";
} }
6.设置定时任务(定时时间所要执行的任务)
public class QuartzJob implements Job{ @Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
for(int i = 0; i < 5;i = i + 1){
for(int j = 0; j < 3; j++){
System.out.println("数组中的平均值"+j);
}
System.out.println("1111111");
}
} }
7.将定时任务添加到JobDetail中
public class QuartzManager {
private static SchedulerFactory schedulerFactory = new StdSchedulerFactory(); /**
* @Description: 添加一个定时任务
*
* @param jobName 任务名
* @param jobGroupName 任务组名
* @param triggerName 触发器名
* @param triggerGroupName 触发器组名
* @param jobClass 任务
* @param cron 时间设置,参考quartz说明文档
*/
@SuppressWarnings({ "rawtypes" })
public static void addJob(String jobName, String jobGroupName, Class jobClass, ScheduleInfo scheduleInfo) {
try {
//调度器
Scheduler sched = schedulerFactory.getScheduler();
// 任务名,任务组,任务执行类
JobDetail jobDetail= new JobDetail(jobName,jobGroupName,jobClass); // 创建Trigger对象 触发器
CronTrigger cronTrigger = new CronTrigger(jobName,jobGroupName);
cronTrigger.setStartTime(scheduleInfo.getStartTime());
cronTrigger.setCronExpression(new CronTriggerUtil().toCronExpr(scheduleInfo));
cronTrigger.setMisfireInstruction(CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING); sched.scheduleJob(jobDetail, cronTrigger); // 启动
if (!sched.isShutdown()) {
sched.start();
} } catch (Exception e) {
}
} /**
* @Description: 开始一个定时任务
*/
public static void startTimingJob(Integer jobType){
UDCTimingSync timeSyncObj = new UDCTimingSync();
timeSyncObj.setStatus(1);
timeSyncObj.setSynctime("20:57:00");
ScheduleInfo schedule_info = new ScheduleInfo();
if(null == timeSyncObj.getStatus()){
return;
}
if(timeSyncObj.getStatus().equals(UDCTimingSync.SWTICH_OFF)){
return;
}
if(timeSyncObj.getStatus().equals(UDCTimingSync.BY_DAY)){//按天
schedule_info.setDateCycle(DateCycle.BY_DAY);
schedule_info.setGranularityPeriod(GranularityPeriod.TWENTY_FOUR_HOURS);
schedule_info.setStartTime(QuartzManager.getStartTime(timeSyncObj.getSynctime()));
}else if(timeSyncObj.getStatus().equals(UDCTimingSync.BY_WEEK)){//按周
schedule_info.setDateCycle(DateCycle.BY_WEEK);
schedule_info.setWeekDays(timeSyncObj.getWeek().toString());
schedule_info.setGranularityPeriod(GranularityPeriod.TWENTY_FOUR_HOURS);
schedule_info.setStartTime(QuartzManager.getStartTime(timeSyncObj.getSynctime()));
}else if(timeSyncObj.getStatus().equals(UDCTimingSync.BY_MONTH)){
schedule_info.setDateCycle(DateCycle.BY_MONTH);
schedule_info.setMonthDays(timeSyncObj.getDay().toString());
schedule_info.setGranularityPeriod(GranularityPeriod.TWENTY_FOUR_HOURS);
schedule_info.setStartTime(QuartzManager.getStartTime(timeSyncObj.getSynctime()));
} QuartzManager.addJob(UDCTimingSync.JOB_TYPE_NAME_MAP.get(jobType).getJobName(),
UDCTimingSync.JOB_TYPE_NAME_MAP.get(jobType).getJobGroupName(), QuartzJob.class, schedule_info);
} /**
* @Description: 将传入的时间转成日历标准时间
*/
public static Date getStartTime(String limitBeginTime) {
Calendar calendar = Calendar.getInstance(); // 获取当前时间
Date currentDate = new Date(System.currentTimeMillis());
calendar.setTime(currentDate);
Date now = calendar.getTime(); String[] begins = limitBeginTime.split(":");
calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(begins[0]));
calendar.set(Calendar.MINUTE, Integer.parseInt(begins[1]));
calendar.set(Calendar.SECOND, Integer.parseInt(begins[2]));
Date beginTime = calendar.getTime(); // 当开始时间小于或者等于当前时间,则将日期增加一天
boolean isGreater = beginTime.after(now);
if (!isGreater) {
calendar.add(Calendar.DAY_OF_MONTH, 1);
} return calendar.getTime();
}
}
8.测试类 调用定时任务
public class QuartzTest { public static void main(String[] args) { initJobs();
}
/**
* @Description: 调用定时任务组,传入定时任务组名
*/
private static void initJobs(){
QuartzManager.startTimingJob(UDCTimingSync.TYPE_IOPS);
System.out.print("now time is"+new Date(System.currentTimeMillis()));
}
}
Quartz定时任务封装的更多相关文章
- 搭建maven web项目并配置quartz定时任务【业务:对比数据变化内容】 历程
搭建maven web项目并配置quartz定时任务[业务:对比数据变化内容] 历程2018年03月03日 10:51:10 守望dfdfdf 阅读数:100更多个人分类: 工作 问题编辑版权声明:本 ...
- Quartz定时任务学习(二)web应用/Quartz定时任务学习(三)属性文件和jar
web中使用Quartz 1.首先在web.xml文件中加入 如下内容(根据自己情况设定) 在web.xml中添加QuartzInitializerServlet,Quartz为能够在web应用中使用 ...
- quartz定时任务框架的使用
quartz定时任务时间设置 这些星号由左到右按顺序代表 : * * * * * * * ...
- Quartz定时任务学习(二)web应用
web中使用Quartz 1.首先在web.xml文件中加入 如下内容(根据自己情况设定) 在web.xml中添加QuartzInitializerServlet,Quartz为能够在web应用中使用 ...
- Quartz定时任务使用小记(11月22日)
骤然接触quartz,先从小处着手,why,what,how quartz定时任务: 为什么使用quartz定时任务,以及定时任务在实际应用场景下的特定需求. 1.用户方面的需要,为了提供更好的使用体 ...
- quartz定时任务时间配置
quartz定时任务时间设置描述(2011-03-03 16:23:50)转载▼标签: quartz时间it 分类: 凌乱小记 这些星号由左到右按顺序代表 : * * * ...
- 对quartz定时任务的初步认识
已经好久没有写技术博文了,今天就谈一谈我前两天自学的quartz定时任务吧,我对quartz定时任务的理解,就是可以设定一个时间,然后呢,在这个时间到的时候,去执行业务逻辑,这是我的简单理解,接下来看 ...
- Spring整合Quartz定时任务执行2次,Spring定时任务执行2次
Spring整合Quartz定时任务执行2次,Spring定时任务执行2次 >>>>>>>>>>>>>>>&g ...
- Quartz 定时任务时间设置
转自https://blog.csdn.net/zdx1515888659/article/details/79158169 quartz定时任务时间设置: 这些星号由左到右按顺序代表 : * * * ...
随机推荐
- Docker Swarm Mode 学习笔记 (基本概念)
Swarm 是使用 SwarmKit 构建的 Docker 引擎内置(原生)的集群管理和编排工具 节点 运行 Docker 的主机可以主动初始化一个 Swarm 集群 docker swarm ...
- mybatis中mapper接口的参数设置几种方法
方法一:忽略parameterType,加@param("xxx")注解 在mapper接口中加上@param("xxx")注解,则在配置文件中直接用即可 Li ...
- centos7 基础命令
一: linux基础 (1) 查看服务器的IP信息 ip add showifconfig (2) 操作网卡命令(重启网络和启用网卡) systemctl restart networksystemc ...
- HDU 1041 Computer Transformation(找规律加大数乘)
主要还是找规律,然后大数相乘 #include<stdio.h> #include<string.h> #include<math.h> #include<t ...
- layui
给大家推荐个比较好用的前端ui框架layui,遵循原生HTML/CSS/JS的书写与组织形式,门槛极低,拿来即用,而且layui除了ie6/7不兼容其他都兼容,而且还是响应式布局 1,获得layui后 ...
- UVALive - 5857 Captain Q's Treasure
UVALive - 5857 思路: 状压dp,用map写 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimi ...
- 算法笔记--manacher算法
参考:https://www.cnblogs.com/grandyang/p/4475985.html#undefined 模板: ; int p[N]; string manacher(string ...
- linux指令(2)
1)获取历史操作命令: "!<history指令编号>”即可运行相应命令 [root@server1 ~]# history.............. 1011 uname - ...
- ubuntu18.04.2LTS下如何用五笔输入法 --Linux
ubuntu18.04.2LTS下自带五笔输入法,不用去单独下载 1.在设置中找到区域和语言 2.点击加号添加输入源 3.选择,选择「汉语」 4.选择「极点五笔」 开始你的五笔输入法之旅…… 友情链接 ...
- springboot junit
1 添加pom依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId& ...