Quartz2.x动态Job工具类

血红的双手。 提交于 2020-04-22 08:21:59

有些需求,需要动态启动一个定时器,然后在一定条件下再停止。比如通过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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!