**
网上很多关于 quartz 动态的改动的文章,但是很多都没有结合springBoot ,还有 jobService(定时任务类)类 必须继承 Job 或者 Runnable ,这样代码不同灵活 ,现在写一遍解决这些问题的记录文章,记录一下解决方式。
**pom 导入quartz pom文件
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
数据库对应实体对象
package com.tangkoukou;
import java.util.Date;
public class SchedulerPojo {
/**
* id
*/
private String id;
/**
* 类名
*/
private String className;
/**
* 方法名
*/
private String methodName;
/**
*任务名称
*/
private String jobName;
/**
* 触发器名称
*/
private String triggerName;
/**
* 触发器分组号
*/
private String triggerGroupName;
/**
* cron 规则
*/
private String cron;
/**
* 开启时间
*/
private Date startTime;
/**
* 结束时间
*/
private Date endTime;
/**
* 发布状态 0 停用 1启用
*/
private String status;
/**
* 备注
*/
private String remark;
/**
* 锁(用于并发或者分布是判断使用)0 未锁 ,1 锁定 (未使用)
*/
private String lock;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public String getTriggerName() {
return triggerName;
}
public void setTriggerName(String triggerName) {
this.triggerName = triggerName;
}
public String getTriggerGroupName() {
return triggerGroupName;
}
public void setTriggerGroupName(String triggerGroupName) {
this.triggerGroupName = triggerGroupName;
}
public String getCron() {
return cron;
}
public void setCron(String cron) {
this.cron = cron;
}
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public String getLock() {
return lock;
}
public void setLock(String lock) {
this.lock = lock;
}
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
@Override
public String toString() {
return "SchedulerPojo{" +
"id='" + id + '\'' +
", className='" + className + '\'' +
", methodName='" + methodName + '\'' +
", jobName='" + jobName + '\'' +
", triggerName='" + triggerName + '\'' +
", triggerGroupName='" + triggerGroupName + '\'' +
", cron='" + cron + '\'' +
", startTime=" + startTime +
", endTime=" + endTime +
", status='" + status + '\'' +
", remark='" + remark + '\'' +
", lock='" + lock + '\'' +
'}';
}
}
server A类
package com.tangkoukou;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class C {
private final Logger logger = LoggerFactory.getLogger(C.class);
public void sayHi1(){
logger.info("C-----sayHi1");
}
public void sayHi2(){
logger.info("C-----sayHi2");
}
}
server D类
package com.eyedsion.his.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class D {
private final Logger logger = LoggerFactory.getLogger(D.class);
public void sayHi1(){
logger.info("D-----sayHi1");
}
}
SchedulerUtil 定时任务工具类
这是才是今天的主角
package com.tangkoukou;
import com.tangkoukou.DateUtil;
import org.quartz.*;
import org.quartz.impl.JobDetailImpl;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.GroupMatcher;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.*;
import java.util.Calendar;
@Component
public class SchedulerUtil {
private Scheduler scheduler ;
@Autowired
private ApplicationContext applicationContext;
public SchedulerUtil() {
try {
scheduler = new StdSchedulerFactory().getScheduler();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
private final Logger logger = LoggerFactory.getLogger(SchedulerUtil.class);
public static void main(String[] args) throws InterruptedException, SchedulerException {
SchedulerUtil schedulerUtil = new SchedulerUtil();
schedulerUtil.initJobAll();
}
/**
* 添加定时任务
* @param schedulerPojo
* @throws SchedulerException
* @throws NoSuchMethodException
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public void addJob(SchedulerPojo schedulerPojo) throws SchedulerException, NoSuchMethodException, ClassNotFoundException, IllegalAccessException, InstantiationException {
MethodInvokingJobDetailFactoryBean jobDetailFactoryBean = new MethodInvokingJobDetailFactoryBean();
// 是否并发执行
jobDetailFactoryBean.setConcurrent(false);
jobDetailFactoryBean.setName(schedulerPojo.getJobName());
//Object targetBean = applicationContext.getBean(Class.forName(schedulerPojo.getClassName())); //TODO 结合springBoot 测试
Object targetBean = Class.forName(schedulerPojo.getClassName()).newInstance();//TODO main 方法测试
// 为需要执行的实体类对应的对象
jobDetailFactoryBean.setTargetObject(targetBean);
// 需要执行的方法
jobDetailFactoryBean.setTargetMethod(schedulerPojo.getMethodName());
// 调度容器设置JobDetail和Trigger
jobDetailFactoryBean.afterPropertiesSet();//生成任务 jobDetail
JobDetail jobDetail = jobDetailFactoryBean.getObject();//获取任务 jobDetail
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
// 触发器名,触发器组
triggerBuilder.withIdentity(schedulerPojo.getTriggerName(), schedulerPojo.getTriggerGroupName());
// 触发器时间设定
triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(schedulerPojo.getCron()));
//设置有效时间段
if(schedulerPojo.getStartTime() == null){
triggerBuilder.startNow();
}else{
triggerBuilder.startAt(schedulerPojo.getStartTime());
}
if(schedulerPojo.getEndTime() != null){
triggerBuilder.endAt(schedulerPojo.getEndTime());
}
// 创建Trigger对象
CronTrigger trigger = (CronTrigger) triggerBuilder.build();//获取触发器
scheduler.scheduleJob(jobDetail, trigger);
}
public void startJobAll(){
try {
if (scheduler.isStarted()) {
System.out.println("定时器已启动。");
} else {
scheduler.start();
}
} catch (SchedulerException e1) {
e1.printStackTrace();
}
}
public void deleteJob(SchedulerPojo schedulerPojo){
try {
TriggerKey triggerKey = TriggerKey.triggerKey(schedulerPojo.getTriggerName(), schedulerPojo.getTriggerGroupName());
// 停止触发器
scheduler.pauseTrigger(triggerKey);
// 移除触发器
scheduler.unscheduleJob(triggerKey);
// 删除任务
scheduler.deleteJob(JobKey.jobKey(schedulerPojo.getJobName(), schedulerPojo.getTriggerGroupName()));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 修改定时任务时间
* 不支持修改要执行的具体方法定时任务
* @param schedulerPojo
*/
public void modifyJobTime(SchedulerPojo schedulerPojo) {
try {
TriggerKey triggerKey = TriggerKey.triggerKey(schedulerPojo.getTriggerName(), schedulerPojo.getTriggerGroupName());
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
if (trigger == null) {
return;
}
String oldTime = trigger.getCronExpression();
if (!oldTime.equalsIgnoreCase(schedulerPojo.getCron())) {
// 触发器
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder
.newTrigger();
// 触发器名,触发器组
triggerBuilder.withIdentity(schedulerPojo.getTriggerName(), schedulerPojo.getTriggerGroupName());
triggerBuilder.startNow();
// 触发器时间设定
triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(schedulerPojo.getCron()));
// 创建Trigger对象
trigger = (CronTrigger) triggerBuilder.build();
// 方式一 :修改一个任务的触发时间
scheduler.rescheduleJob(triggerKey, trigger);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 指定更新
*/
public void replaceJob(SchedulerPojo schedulerPojo) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, SchedulerException, IllegalAccessException {
//先删除在添加
deleteJob(schedulerPojo);
addJob(schedulerPojo);
}
/**
* 全部更新
*
*/
public void replaceJobAll() throws SchedulerException {
deleteJobAll();
initJobAll();
}
/**
* 移出所有
*/
public void deleteJobAll() throws SchedulerException {
scheduler.clear();
}
/**
* 立即执行单个(待编写)
*/
/**
* 关闭单个(待编写)
*/
/**
* 功能:关闭所有定时任务
*/
public void shutdownJobs() {
try {
if (!scheduler.isShutdown()) {
scheduler.shutdown();
}
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 查看全部
* @return
*/
public List<SchedulerPojo> getAllJobs() {
List<SchedulerPojo> schedulerPojoList = new ArrayList<>();
try {
//再获取Scheduler下的所有group
List<String> triggerGroupNames = scheduler.getTriggerGroupNames();
for (String groupName : triggerGroupNames) {
//组装group的匹配,为了模糊获取所有的triggerKey或者jobKey
GroupMatcher groupMatcher = GroupMatcher.groupEquals(groupName);
//获取所有的triggerKey
Set<TriggerKey> triggerKeySet = scheduler.getTriggerKeys(groupMatcher);
for (TriggerKey triggerKey : triggerKeySet) {
//通过triggerKey在scheduler中获取trigger对象
CronTriggerImpl trigger = (CronTriggerImpl)scheduler.getTrigger(triggerKey);
//获取trigger拥有的Job
JobKey jobKey = trigger.getJobKey();
JobDetailImpl jobDetail = (JobDetailImpl) scheduler.getJobDetail(jobKey);
JobDataMap jobDataMap = jobDetail.getJobDataMap();
MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean = (MethodInvokingJobDetailFactoryBean)jobDataMap.get("methodInvoker");
//组装页面需要显示的数据
SchedulerPojo schedulerPojo = new SchedulerPojo();
schedulerPojo.setClassName(methodInvokingJobDetailFactoryBean.getTargetClass().getName());
schedulerPojo.setMethodName(methodInvokingJobDetailFactoryBean.getTargetMethod());
schedulerPojo.setStartTime(trigger.getStartTime());
schedulerPojo.setEndTime(trigger.getEndTime());
schedulerPojo.setTriggerGroupName(groupName);
schedulerPojo.setTriggerName( trigger.getName());
schedulerPojo.setJobName(jobDetail.getName());
schedulerPojo.setCron(trigger.getCronExpression());
schedulerPojo.setId(trigger.getTimeZone().getID());
schedulerPojoList.add(schedulerPojo);
}
}
} catch (Exception e) {
logger.error("获取定时任务信息出错", e);
}
return schedulerPojoList;
}
/**
* 初始化全部定时任务
*/
@PostConstruct
public void initJobAll(){
//这里我是手动造的数据,模拟数据库连接
SchedulerPojo schedulerPojo1 = new SchedulerPojo();
schedulerPojo1.setJobName("schedulerPojo-1");
schedulerPojo1.setClassName("com.tangKouKou.C");
schedulerPojo1.setMethodName("sayHi1");
schedulerPojo1.setTriggerName("C");
schedulerPojo1.setTriggerGroupName("C-sayHi1");
schedulerPojo1.setCron(" 0/20 * * * * ?");
schedulerPojo1.setStatus("1");
schedulerPojo1.setStartTime(DateUtil.datesAdd(new Date(),1, Calendar.MINUTE));
schedulerPojo1.setEndTime(DateUtil.datesAdd(new Date(),2, Calendar.MINUTE));
SchedulerPojo schedulerPojo2 = new SchedulerPojo();
schedulerPojo2.setJobName("schedulerPojo-2");
schedulerPojo2.setClassName("com.tangKouKou.D");
schedulerPojo2.setMethodName("sayHi1");
schedulerPojo2.setTriggerName("D");
schedulerPojo2.setTriggerGroupName("D-sayHi");
schedulerPojo2.setCron(" 0/5 * * * * ?");
schedulerPojo2.setStatus("1");
List<SchedulerPojo> schedulerPojoList = new ArrayList();
schedulerPojoList.add(schedulerPojo1);
schedulerPojoList.add(schedulerPojo2);
for(SchedulerPojo schedulerPojo : schedulerPojoList){
try {
addJob(schedulerPojo);
} catch (SchedulerException e) {
e.printStackTrace();
logger.error(e.getMessage());
} catch (NoSuchMethodException e) {
e.printStackTrace();
logger.error(e.getMessage());
} catch (ClassNotFoundException e) {
e.printStackTrace();
logger.error(e.getMessage());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
startJobAll();
}
}
打印结果