有些需求,需要动态启动一个定时器,然后在一定条件下再停止。比如通过rest控制jenkins做发布,当发起一个构建后,就需要定时去查询构建状态,在构建完成后再停止定时器,下面是一个通用的定时器工具类。
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.scc</groupId>
<artifactId>stu-quartz</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</build>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>log4j-over-slf4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>21.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
</dependencies>
</project>
接口
package com.scc.quartz;
import java.util.Map;
import org.quartz.Job;
/**
* @ClassName: IQuartzManager
* @Description: TODO(这里用一句话描述这个类的作用)
* @author shangchengcai@voole.com
* @date 2017年4月18日 下午3:48:50
*
*/
public interface IQuartzManager {
/**
*
* @Title: addJob
* @Description: TODO(这里用一句话描述这个方法的作用)
* @author shangchengcai@voole.com
* @date 2017年4月18日 下午3:49:09
* @param job_key
* @param cls
* @param delay 单位分钟
* @param interval 单位秒
* @param args
* @return
*/
boolean addAndStartJob(String job_key, Class<? extends Job> cls, Integer delay, Integer interval,
Map<String, Object> args);
/**
*
* @Title: deleteJob
* @Description: TODO(这里用一句话描述这个方法的作用)
* @author shangchengcai@voole.com
* @date 2017年4月18日 下午3:49:16
* @param job_key
* @return
*/
boolean deleteJob(String job_key);
}
实现
package com.scc.quartz.impl;
import java.util.Date;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;
import com.google.common.base.Preconditions;
import com.scc.quartz.IQuartzManager;
/**
* @ClassName: QuartzManagerImpl
* @Description: TODO(这里用一句话描述这个类的作用)
* @author shangchengcai@voole.com
* @date 2017年9月30日 下午2:26:12
*
*/
@Service
public class QuartzManagerImpl implements IQuartzManager {
private static final Logger LOGGER = LoggerFactory.getLogger(QuartzManagerImpl.class);
@Autowired
private SchedulerFactoryBean schedulerFactoryBean;
private static String JOB_GROUP_NAME = "EXTJWEB_JOBGROUP_NAME";
/*
* (非 Javadoc) <p>Title: addJob</p> <p>Description: </p>
*
* @param job_key
*
* @param cls
*
* @param delay
*
* @param interval
*
* @param args
*
* @see com.voole.datacheck.util.quartz.IQuartzManager#addJob(java.lang.String, java.lang.Class, java.lang.String,
* java.util.Map)
*/
@Override
public boolean addAndStartJob(String job_key, Class<? extends Job> cls, Integer delay, Integer interval,
Map<String, Object> args) {
LOGGER.info("add job:jobName-" + job_key + ",cls-" + cls + ",delay-" + delay);
Preconditions.checkArgument(StringUtils.isNotBlank(job_key), "jobName can not be null");
Preconditions.checkArgument(cls != null, "cls can not be null");
try {
JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(job_key, JOB_GROUP_NAME).build();// 任务名,任务组,任务执行类
jobDetail.getJobDataMap().putAll(args);
// 触发器
TriggerKey triggerKey = TriggerKey.triggerKey(job_key, JOB_GROUP_NAME);
// 表达式调度构建器
SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(interval).repeatForever();
// .withRepeatCount(0);
Long currentdatetime = System.currentTimeMillis();
Date rundate = new Date(currentdatetime + ((null == delay ? 60 : delay) * 60 * 1000));
SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).startAt(rundate)
.withSchedule(scheduleBuilder).build();
this.getScheduler().scheduleJob(jobDetail, trigger);
return true;
} catch (Exception e) {
LOGGER.error("", e);
e.printStackTrace();
}
return false;
}
/**
* @Title: getScheduler
* @Description: TODO(这里用一句话描述这个方法的作用)
* @author shangchengcai@voole.com
* @date 2017年4月18日 下午5:43:52
* @return
*/
private Scheduler getScheduler() {
return this.schedulerFactoryBean.getScheduler();
}
/*
* (非 Javadoc) <p>Title: deleteJob</p> <p>Description: </p>
*
* @param job_key
*
* @return
*
* @see com.voole.datacheck.util.quartz.IQuartzManager#deleteJob(java.lang.String)
*/
@Override
public boolean deleteJob(String job_key) {
LOGGER.info("deleteJob:job_name-" + job_key);
Preconditions.checkArgument(StringUtils.isNotBlank(job_key), "jobName can not be null");
JobKey jobKey = JobKey.jobKey(job_key, JOB_GROUP_NAME);
try {
if (this.getScheduler().checkExists(jobKey)) {
this.getScheduler().pauseJob(jobKey);
this.getScheduler().deleteJob(jobKey);
}
return true;
} catch (SchedulerException e) {
LOGGER.error("", e);
e.printStackTrace();
}
return false;
}
}
配置
package com.scc.conf;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
/**
* @ClassName: XMLConfig
* @Description: TODO(这里用一句话描述这个类的作用)
* @author shangchengcai@voole.com
* @date 2017年9月6日 下午3:45:47
*
*/
@Configuration
public class Config {
/**
*
* @Title: schedulerFactoryBean
* @Description: TODO(这里用一句话描述这个方法的作用)
* @author chengcai.shang@cmgplex.com
* @date 2018年9月14日 上午9:33:24
* @return
*/
@Bean
public SchedulerFactoryBean schedulerFactoryBean() {
return new SchedulerFactoryBean();
}
}
启动类
package com.scc;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.scc.demojob.DemoJob;
import com.scc.quartz.IQuartzManager;
/**
* @ClassName: Application
* @Description: TODO(这里用一句话描述这个类的作用)
* @author shangchengcai@voole.com
* @date 2017年9月7日 上午9:50:19
*
*/
@SpringBootApplication
@Controller
public class Application {
@Resource
private IQuartzManager quartzManager;
@RequestMapping("/start")
@ResponseBody
public String testStart() {
Map<String, Object> args = new HashMap<>();
args.put("args1", "args1");
args.put("args2", "args2");
args.put("args3", "args3");
args.put("args4", "args4");
this.quartzManager.addAndStartJob("test", DemoJob.class, 0, 5, args);
return "success";
}
@RequestMapping("/stop")
@ResponseBody
public String testStop() {
this.quartzManager.deleteJob("test");
return "success";
}
@RequestMapping("/killSelf")
@ResponseBody
public String testKillSelf() {
Map<String, Object> args = new HashMap<>();
args.put("quartzManager", this.quartzManager);
this.quartzManager.addAndStartJob("test", DemoJob.class, 0, 5, args);
return "success";
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
接口说明
总共有三个接口,start、stop、killSelf。顾名思义,前两个略过,最后一个是在启动后,判断是否具备停止条件,一但具备就停止当前定时。
具体代码见https://github.com/shang7053/base/tree/master/stu-quartz
来源:oschina
链接:https://my.oschina.net/u/2358114/blog/2051251