一、项目说明
项目环境:jdk1.7+tomcat7+idea2018+quartz2.3.0+maven+mysql5.1.40
源代码github地址:https://github.com/tmAlj/ssmz
实现目标:项目采用的是simpleTrigger触发方式,实现了动态的添加,删除,修改,暂停,开启任务,同时持久化到数据库
二、整合步骤(默认除quartz以外其他配置已整合)
(1)pom.xml中添加quartz依赖(下载地址:http://mvnrepository.com/)
<!-- quartz依赖start -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
<!-- quartz依赖end -->
(2)新建quartz配置文件quartz.properties
注:数据库连接需改为自己的,数据库表在项目/WEB-INF/ sql/目录下,导入表后需清空所有表中数据
# Default Properties file for use by StdSchedulerFactory
# to create a Quartz Scheduler Instance, if a different
# properties file is not explicitly specified.
#
#============================================================================
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName: quartzScheduler
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: 2
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true
org.quartz.jobStore.misfireThreshold: 60000
#============================================================================
# Configure JobStore
#============================================================================
#default config
#org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
#\u6301\u4e45\u5316\u914d\u7f6e
org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties:true
#============================================================================
#havent cluster spring
#============================================================================
org.quartz.jobStore.isClustered = false
#\u6570\u636e\u5e93\u8868\u524d\u7f00
org.quartz.jobStore.tablePrefix:qrtz_
org.quartz.jobStore.dataSource:qzDS
#============================================================================
# Configure Datasources
#============================================================================
org.quartz.dataSource.qzDS.driver:com.mysql.jdbc.Driver
org.quartz.dataSource.qzDS.URL:jdbc:mysql://localhost:3306/quartz
org.quartz.dataSource.qzDS.user:root
org.quartz.dataSource.qzDS.password:root
#org.quartz.dataSource.qzDS.maxConnection:10
(3)在spring-config.xml中配置Scheduler
<!--配置Quartz-->
<bean name="quartzScheduler" id="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" >
<property name="dataSource" ref ="dataSource" />
<property name="applicationContextSchedulerContextKey" value="applicationContextKey"/>
<property name="configLocation" value="classpath:quartz.properties"/>
</bean>
(4)controller层
package com.wsd.controller;
import com.alibaba.fastjson.JSONObject;
import com.wsd.service.QuartzService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
/**
* Created by tm on 2018/7/19.
* 定时任务controller类
*/
@Controller
@RequestMapping("/quartz")
public class QuartzController {
@Autowired
QuartzService qs;
/**
* job列表
* @param model
* @return
*/
@RequestMapping(value = "/listJob")
public String jobList(Model model){
model.addAttribute("jobs",qs.queryJobs());
return "listJob";
}
/**
* 暂停job
* @param jobName job名称
* @param jobGroup job组
* @return
*/
@RequestMapping(value="/pauseJob",method=RequestMethod.POST)
@ResponseBody
public String pauseJob(@RequestParam("jobName") String jobName, @RequestParam("jobGroup") String jobGroup){
JSONObject json = new JSONObject();
System.out.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxjob暂停了=>"+jobName+"<=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
if(StringUtils.isEmpty(jobName) || StringUtils.isEmpty(jobGroup)){
json.put("status", "wrong");
}else{
qs.pauseJob(jobName, jobGroup);
json.put("status", "success");
}
return json.toJSONString();
}
/**
* 重启job
* @param jobName job名称
* @param jobGroup job组
* @return
*/
@RequestMapping(value="/resumeJob",method=RequestMethod.POST)
@ResponseBody
public String resumeJob(@RequestParam("jobName") String jobName, @RequestParam("jobGroup") String jobGroup){
JSONObject json = new JSONObject();
System.out.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxjob重启了=>"+jobName+"<=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
if(StringUtils.isEmpty(jobName) || StringUtils.isEmpty(jobGroup)){
json.put("status", "wrong");
}else{
qs.resumeJob(jobName, jobGroup);
json.put("status", "success");
}
return json.toJSONString();
}
/**
* 删除job
* @param jobName
* @param jobGroup
* @param triggerName
* @param triggerGroup
* @return
*/
@RequestMapping(value="/removeJob",method=RequestMethod.POST)
@ResponseBody
public String deleteJob(@RequestParam("jobName") String jobName,@RequestParam("jobGroup") String jobGroup,
@RequestParam("triggerName") String triggerName,@RequestParam("triggerGroup") String triggerGroup ){
JSONObject json = new JSONObject();
System.out.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxjob删除了=>"+jobName+"<=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
if(StringUtils.isEmpty(jobName) || StringUtils.isEmpty(jobGroup) ||
StringUtils.isEmpty(triggerName) || StringUtils.isEmpty(triggerGroup) ){
json.put("status", "wrong");
}else{
qs.removeJob(jobName, jobGroup, triggerName, triggerGroup);
json.put("status", "success");
}
return json.toJSONString();
}
/**
* 新增job
* @return
*/
@RequestMapping(value="/addJob",method=RequestMethod.POST)
@ResponseBody
public String addJob(HttpServletRequest request){
JSONObject json = new JSONObject();
String triggerGroup = request.getParameter("triggerGroup");
String triggerName = request.getParameter("triggerName");
String jobGroup = request.getParameter("jobGroup");
String jobName = request.getParameter("jobName");
String jobClassName = request.getParameter("jobClassName");
String jobInterval = request.getParameter("jobInterval");
int interval = Integer.parseInt(jobInterval);
System.out.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxjob新增了=>"+jobName+"<=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
if(StringUtils.isEmpty(triggerGroup) || StringUtils.isEmpty(triggerName) ||
StringUtils.isEmpty(jobGroup) || StringUtils.isEmpty(jobName) ||
StringUtils.isEmpty(jobClassName) || StringUtils.isEmpty(jobInterval)){
json.put("status", "wrong");
}else{
qs.addJob(jobName, jobGroup, triggerName, triggerGroup, jobClassName, interval);
json.put("status", "success");
}
return json.toJSONString();
}
/**
* 更新job
* @return
*/
@RequestMapping(value="/updateJob",method=RequestMethod.POST)
@ResponseBody
public String updateJob(@RequestParam("jobName") String jobName,@RequestParam("jobGroup") String jobGroup,
@RequestParam("triggerName") String triggerName,@RequestParam("triggerGroup") String triggerGroup,
@RequestParam("oldTriggerName") String oldTriggerName,@RequestParam("oldTriggerGroup") String oldTriggerGroup,
@RequestParam("oldJobName") String oldJobName,@RequestParam("oldJobGroup") String oldJobGroup,
@RequestParam("jobClassName") String jobClassName,@RequestParam("jobInterval") int jobInterval){
JSONObject json = new JSONObject();
System.out.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxjob修改了=>"+jobName+"<=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
if(StringUtils.isEmpty(oldTriggerName) || StringUtils.isEmpty(oldTriggerGroup) ||
StringUtils.isEmpty(oldJobName) || StringUtils.isEmpty(oldJobGroup)||
StringUtils.isEmpty(triggerGroup) || StringUtils.isEmpty(triggerName) ||
StringUtils.isEmpty(jobGroup) || StringUtils.isEmpty(jobName) ||
StringUtils.isEmpty(jobClassName) || StringUtils.isEmpty(jobInterval)){
json.put("status", "wrong");
}else{
qs.removeJob(oldJobName, oldJobGroup, oldTriggerName, oldTriggerGroup);
qs.addJob(jobName, jobGroup, triggerName, triggerGroup, jobClassName, jobInterval);
json.put("status", "success");
}
return json.toJSONString();
}
}
(5)service层
package com.wsd.service;
import com.wsd.dao.QuartzDao;
import com.wsd.model.JobEntity;
import com.wsd.service.impl.QuartzImpl;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;
/**
* Created by tm on 2018/7/19.
* 定时任务service类
*/
@Service
public class QuartzService implements QuartzImpl {
@Autowired
Scheduler scheduler; //注入scheduler,需要在spring-config.xml配置
@Autowired
QuartzDao ud; //注入dao
/**
* 获取job列表
* @return
*/
public List<JobEntity> queryJobs(){
return ud.queryJobs();
}
/**
* 暂停job
* @param jobName job名称
* @param jobGroup jog组
*/
public void pauseJob(String jobName, String jobGroup) {
try {
scheduler.pauseJob(JobKey.jobKey(jobName, jobGroup));
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 恢复job
* @param jobName job名称
* @param jobGroup jog组
*/
public void resumeJob(String jobName, String jobGroup) {
try {
scheduler.resumeJob(JobKey.jobKey(jobName, jobGroup));
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 删除job
* @param jobName job名称
* @param jobGroup job组
* @param triggerName trigger名称
* @param triggerGroup trigger组
*/
public void removeJob(String jobName, String jobGroup, String triggerName, String triggerGroup) {
Scheduler sched = scheduler;
try {
// 停止触发器
sched.pauseTrigger(TriggerKey.triggerKey(triggerName,
jobGroup));
// 移除触发器
sched.unscheduleJob(TriggerKey.triggerKey(triggerName,
jobGroup));
// 删除任务
sched.deleteJob(JobKey.jobKey(jobName, jobGroup));
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 添加job
* @param jobName job名称
* @param jobGroup job组
* @param triggerName trigger名称
* @param triggerGroup trigger组
* @param jobClassName job类路径
* @param time job执行间隔时间
*/
public void addJob(String jobName, String jobGroup, String triggerName, String triggerGroup, String jobClassName, int time){
try {
Scheduler sd = scheduler;
//Trigger与Job的关系为1:N
//定义一个Trigger
Trigger trigger = newTrigger().withIdentity(triggerName, triggerGroup) //定义trigger的name/group
.startNow()
.withSchedule(simpleSchedule() //使用SimpleTrigger
.withIntervalInSeconds(time)
.repeatForever())
.build();
//定义一个JobDetail
Class jobClass = Class.forName(jobClassName);
JobDetail job = newJob(jobClass)
.withIdentity(jobName, jobGroup) //定义job的name/group
.build();
//加入这个调度
sd.scheduleJob(job, trigger);
sd.start();
} catch (SchedulerException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
(6)job类
package com.wsd.quartz;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.util.Date;
/**
* Created by tm on 2018/8/7.
*/
public class Job1 implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException {
JobDetail detail = context.getJobDetail();
System.out.println(" 我是job1=>" + new Date());
}
}
(7)实现效果示例
A:任务列表
B:新增任务
附:
参考地址:https://www.cnblogs.com/drift-ice/p/3817269.html
参考地址:https://blog.csdn.net/u010648555/article/details/54863144
参考地址:http://www.quartz-scheduler.org/documentation/quartz-2.2.x/configuration/
参考地址:https://blog.csdn.net/chungle2011/article/details/52690050