设计思路: 1:通过任务名称结合反射动态拼接组成任务(jobdetail),并注入参数,实现真正的动态创建定时任务 2:可以修改时间在不重启服务的基础上 3:可以立即执行某个任务 4:重启服务后要扫描所有有效任务并启动 5:支持再不重启服务的基础上 暂停,恢复,删除任务 6: 只需要一张表 7: 代码不能上传,只能硬贴啦,对于伸手党抱歉,代码均已运行保证正确,若有错误可以给我留言
--定时任务 oracle版的sql
--job_status 是任务的状态 0启用1暂停
--task_parameter代表任务的方法参数 用逗号分割,按照顺序
CREATE TABLE quartz_config (
job_name VARCHAR2(50 BYTE),
job_group VARCHAR2(50 BYTE),
job_description VARCHAR2(500 BYTE),
cron_expression VARCHAR2(500 BYTE),
job_status NUMBER(10, 0),
create_time DATE,
update_time DATE,
create_user VARCHAR2(255 BYTE),
task_parameter VARCHAR2(4000 BYTE),
PRIMARY KEY ( job_name, job_group )
)
TaskRunner.java
package com.itstyle.quartz.config;
import java.util.List;
import javax.annotation.Resource;
import org.quartz.Scheduler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import com.itstyle.quartz.dynamicquery.Service.QuartzConfigService;
import com.itstyle.quartz.entity.QuartzConfigModel;
import com.itstyle.quartz.web.JobService;
/**
* 启动时扫描所有的有效定时任务并启动
*/
@Component
public class TaskRunner implements ApplicationRunner {
private final static Logger LOGGER = LoggerFactory.getLogger(TaskRunner.class);
private final Integer VALID = 0;
@Resource
Scheduler scheduler;
@Resource
QuartzConfigService quartzConfigService;
@Resource
JobService jobService;
@Override
public void run(ApplicationArguments var) throws Exception {
LOGGER.info("初始化任务");
List<QuartzConfigModel> quartzs = quartzConfigService.findByCondition(null, null, VALID);
if (!CollectionUtils.isEmpty(quartzs)) {
quartzs.forEach(n -> {
try {
jobService.startJob(n.getId().getJobName(), n.getId().getJobGroup(), n.getJobDescription(),
n.getTaskParameter(), n.getCronExpression());
} catch (Exception e) {
LOGGER.error("初始化任务失败");
}
});
}
}
}
GenericRepository.java
package com.itstyle.quartz.dynamicquery.Repository;
import java.io.Serializable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.NoRepositoryBean;
/**
*
*
* @param <T>
* @param <ID>
*/
@NoRepositoryBean
public interface GenericRepository<T, ID extends Serializable>
extends JpaRepository<T, ID>, JpaSpecificationExecutor<T> {
}
QuartzConfigRepository.java
package com.itstyle.quartz.dynamicquery.Repository;
import org.springframework.stereotype.Repository;
import com.itstyle.quartz.entity.QuartzConfigModel;
import com.itstyle.quartz.entity.identity.QuartzConfigIdentity;
@Repository
public interface QuartzConfigRepository extends GenericRepository<QuartzConfigModel, QuartzConfigIdentity> {
}
QuartzConfigServiceImpl.java
package com.itstyle.quartz.dynamicquery.Service.Impl;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.itstyle.quartz.dynamicquery.Repository.QuartzConfigRepository;
import com.itstyle.quartz.dynamicquery.Service.GenericRepositoryServiceImpl;
import com.itstyle.quartz.dynamicquery.Service.QuartzConfigService;
import com.itstyle.quartz.entity.QuartzConfigModel;
import com.itstyle.quartz.entity.identity.QuartzConfigIdentity;
@SuppressWarnings("all")
@Service
public class QuartzConfigServiceImpl
extends GenericRepositoryServiceImpl<QuartzConfigModel, QuartzConfigIdentity, QuartzConfigRepository>
implements QuartzConfigService {
@Autowired
QuartzConfigRepository repository;
@Override
public List<QuartzConfigModel> findByCondition(String jobName, String jobGroup, Integer jobStatus) {
return findAll(findByConditionSpec(jobName, jobGroup, jobStatus));
}
private Specification<QuartzConfigModel> findByConditionSpec(String jobName, String jobGroup, Integer jobStatus) {
return new Specification<QuartzConfigModel>() {
@Override
public Predicate toPredicate(Root<QuartzConfigModel> root, CriteriaQuery<?> query,
CriteriaBuilder criteriaBuilder) {
List<Predicate> predicates = new ArrayList<Predicate>();
if (!StringUtils.isEmpty(jobName)) {
predicates.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("id").get("jobName"), jobName)));
}
if (!StringUtils.isEmpty(jobGroup)) {
predicates
.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("id").get("jobGroup"), jobGroup)));
}
if (jobStatus != null) {
predicates.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("jobStatus"), jobStatus)));
}
query.where(predicates.toArray(new Predicate[predicates.size()]));
return query.getRestriction();
}
};
}
}
GenericRepositoryService.java
package com.itstyle.quartz.dynamicquery.Service;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import com.itstyle.quartz.dynamicquery.Repository.GenericRepository;
/**
*
*
* @param <CT>
* @param <KT>
* @param <RT>
*/
public interface GenericRepositoryService<CT, KT extends Serializable, RT extends GenericRepository<CT, KT>> {
List<CT> findAll();
Page<CT> findAll(Pageable pageable);
Page<CT> findAll(String searchTerm, Pageable pageable);
Page<CT> findAll(Specification<CT> spec, Pageable pageable);
List<CT> findAll(Specification<CT> spec);
CT findOne(KT id);
CT save(CT entity);
List<CT> save(List<CT> entities);
long count();
long count(Specification<CT> spec);
void delete(CT entity);
void delete(KT id);
void deleteAll();
void deleteInBatch(List<CT> entities);
CT saveAndFlush(CT entity);
boolean exists(KT id);
void executeQuery(String sqlString);
CT findOneByPrimaryKeyValue(String fieldName, Object value);
void executeNamedQuery(String sqlString);
void executeNamedQuery(String sqlString, HashMap<String, String> map);
CT findOne(Specification<CT> spec);
}
GenericRepositoryServiceImpl.java
package com.itstyle.quartz.dynamicquery.Service;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import javax.persistence.LockModeType;
import org.hibernate.exception.ConstraintViolationException;
import org.hibernate.id.IdentifierGenerationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.Lock;
import org.springframework.transaction.annotation.Transactional;
import com.itstyle.quartz.dynamicquery.Repository.GenericRepository;
public abstract class GenericRepositoryServiceImpl<CT, KT extends Serializable, RT extends GenericRepository<CT, KT>>
implements GenericRepositoryService<CT, KT, RT> {
private final Logger LOGGER = LoggerFactory.getLogger(getClass());
@Autowired
private GenericRepository<CT, KT> repository;
@Override
public List<CT> findAll() {
LOGGER.debug("findAll");
return repository.findAll();
}
@Override
public Page<CT> findAll(Pageable pageable) {
LOGGER.debug("findAll");
return repository.findAll(pageable);
}
@Override
public Page<CT> findAll(String searchTerm, Pageable pageable) {
return null;
}
@Override
public Page<CT> findAll(Specification<CT> spec, Pageable pageable) {
LOGGER.debug("findAll->Specification:{}, Pageable:{}", spec, pageable);
return repository.findAll(spec, pageable);
}
@Override
public List<CT> findAll(Specification<CT> spec) {
LOGGER.debug("findAll->Specification:{}", spec);
return repository.findAll(spec);
}
@Override
@Transactional
@Lock(LockModeType.WRITE)
public CT save(CT entity) {
LOGGER.debug("GenericRepositoryService#save");
try {
return repository.save(entity);
} catch (IdentifierGenerationException e) {
// 未定义数据主键值
} catch (ConstraintViolationException e) {
// 外键关联数据不存在
}
return null;
}
@Override
@Transactional
@Lock(LockModeType.WRITE)
public List<CT> save(List<CT> entities) {
LOGGER.debug("GenericRepositoryService#save");
try {
return repository.saveAll(entities);
} catch (IdentifierGenerationException e) {
// 未定义数据主键值
} catch (ConstraintViolationException e) {
// 外键关联数据不存在
} catch (IllegalArgumentException e) {
// 非法参数异常
}
return null;
}
@Override
@Transactional
@Lock(LockModeType.WRITE)
public CT saveAndFlush(CT entity) {
LOGGER.debug("saveAndFlush");
return repository.saveAndFlush(entity);
}
@Override
// @Transactional(readOnly = true)
public long count() {
LOGGER.debug("count");
return repository.count();
}
@Override
// @Transactional(readOnly = true)
public long count(Specification<CT> spec) {
LOGGER.debug("count");
return repository.count(spec);
}
@Override
// @Transactional(readOnly = true)
public boolean exists(KT id) {
LOGGER.debug("exists");
return repository.existsById(id);
}
@Override
@Transactional
@Lock(LockModeType.WRITE)
public void delete(CT entity) {
LOGGER.debug("delete# Parameter:{}", entity);
if (entity != null) {
repository.delete(entity);
}
}
@Override
@Transactional
@Lock(LockModeType.WRITE)
public void delete(KT id) {
LOGGER.debug("delete# Parameter:{}", id);
repository.deleteById(id);
}
@Override
@Transactional
@Lock(LockModeType.WRITE)
public void deleteAll() {
LOGGER.debug("deleteAll");
repository.deleteAll();
}
@Override
@Transactional
@Lock(LockModeType.WRITE)
public void deleteInBatch(List<CT> entities) {
LOGGER.debug("deleteInBatch");
repository.deleteInBatch(entities);
}
@Override
public void executeQuery(String sqlString) {
}
@Override
public void executeNamedQuery(String sqlString) {
}
@Override
public void executeNamedQuery(String sqlString, HashMap<String, String> map) {
}
@Override
public CT findOne(KT id) {
LOGGER.debug("GenericRepositoryService#findOne(KT)");
Optional<CT> bean = repository.findById(id);
if (bean.isPresent()) {
return bean.get();
} else {
return null;
}
// return repository.findById(id).get();
}
@Override
public CT findOneByPrimaryKeyValue(String fieldName, Object value) {
return null;
}
@Override
public CT findOne(Specification<CT> spec) {
Optional<CT> option = repository.findOne(spec);
if (option.isPresent()) {
return option.get();
} else {
return null;
}
}
}
QuartzConfigService.java
package com.itstyle.quartz.dynamicquery.Service;
import java.util.List;
import com.itstyle.quartz.dynamicquery.Repository.QuartzConfigRepository;
import com.itstyle.quartz.entity.QuartzConfigModel;
import com.itstyle.quartz.entity.identity.QuartzConfigIdentity;
public interface QuartzConfigService
extends GenericRepositoryService<QuartzConfigModel, QuartzConfigIdentity, QuartzConfigRepository> {
List<QuartzConfigModel> findByCondition(String jobName, String jobGroup, Integer jobStatus);
}
QuartzConfigIdentity.java
package com.itstyle.quartz.entity.identity;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
@Embeddable
public class QuartzConfigIdentity implements Serializable {
/**
*
*/
private static final long serialVersionUID = -6107873034694904498L;
@Column(name = "JOB_NAME")
private String jobName;// 任务名称
@Column(name = "JOB_GROUP")
private String jobGroup;// 任务分组
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public String getJobGroup() {
return jobGroup;
}
public void setJobGroup(String jobGroup) {
this.jobGroup = jobGroup;
}
public QuartzConfigIdentity(String jobName, String jobGroup) {
super();
this.jobName = jobName;
this.jobGroup = jobGroup;
}
public QuartzConfigIdentity() {
super();
// TODO Auto-generated constructor stub
}
}
QuartzConfigModel.java
package com.itstyle.quartz.entity;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Table;
import com.itstyle.quartz.entity.identity.QuartzConfigIdentity;
/**
* 任务类 创建者
*/
@Entity
@Table(name = "QUARTZ_CONFIG")
public class QuartzConfigModel implements Serializable {
/**
*
*/
private static final long serialVersionUID = 2001992304078127000L;
@EmbeddedId
private QuartzConfigIdentity id;
@Column(name = "JOB_DESCRIPTION")
private String jobDescription;// 任务描述
@Column(name = "CRON_EXPRESSION")
private String cronExpression;// 执行时间
@Column(name = "JOB_STATUS")
private Integer jobStatus;// 任务状态
@Column(name = "CREATE_TIME")
private Date createTime;// 创建时间
@Column(name = "UPDATE_TIME")
private Date updateTime;// 更新时间
@Column(name = "CREATE_USER")
private String createUser;// 创建者
@Column(name = "TASK_PARAMETER")
private String taskParameter;
public String getTaskParameter() {
return taskParameter;
}
public void setTaskParameter(String taskParameter) {
this.taskParameter = taskParameter;
}
public String getJobDescription() {
return jobDescription;
}
public void setJobDescription(String jobDescription) {
this.jobDescription = jobDescription;
}
public String getCronExpression() {
return cronExpression;
}
public void setCronExpression(String cronExpression) {
this.cronExpression = cronExpression;
}
public Integer getJobStatus() {
return jobStatus;
}
public void setJobStatus(Integer jobStatus) {
this.jobStatus = jobStatus;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public String getCreateUser() {
return createUser;
}
public void setCreateUser(String createUser) {
this.createUser = createUser;
}
public QuartzConfigIdentity getId() {
return id;
}
public void setId(QuartzConfigIdentity id) {
this.id = id;
}
@PrePersist
public void save() {
createTime = new Date();
jobStatus = 0;
}
@PreUpdate
public void update() {
updateTime = new Date();
}
}
ResponseData.java
package com.itstyle.quartz.entity;
import org.springframework.http.ResponseEntity;
public class ResponseData<T> {
public int code;
public Boolean success;
public T data;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public Boolean getSuccess() {
return success;
}
public void setSuccess(Boolean success) {
this.success = success;
}
public ResponseData() {
super();
this.code = 0;
this.success = Boolean.TRUE;
}
public ResponseData(T data) {
super();
this.code = 0;
this.success = Boolean.TRUE;
this.data = data;
}
public ResponseData(int code, Boolean success, T data) {
super();
this.code = code;
this.success = success;
this.data = data;
}
public static <T> ResponseEntity<?> ok() {
return ResponseEntity.ok(new ResponseData());
}
public static <T> ResponseEntity<?> ok(T data) {
return ResponseEntity.ok(new ResponseData(data));
}
public static ResponseEntity<?> error() {
return ResponseEntity.ok(new ResponseData(-1, false, null));
}
public static ResponseEntity<?> error(String errorCode) {
return ResponseEntity.ok(new ResponseData(-1, false, errorCode));
}
public static ResponseEntity<?> error(Throwable t) {
return ResponseEntity.ok(new ResponseData(-1, false, t));
}
}
DynamicQuartzJob.java
package com.itstyle.quartz.job;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;
import org.quartz.impl.JobDetailImpl;
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.QuartzJobBean;
import org.springframework.util.StringUtils;
/**
* 动态定时任务Job
*
* @author linrx1
*
*/
@PersistJobDataAfterExecution
@DisallowConcurrentExecution // 不允许并发执行
public class DynamicQuartzJob extends QuartzJobBean {
private static final Logger logger = LoggerFactory.getLogger(DynamicQuartzJob.class);
@Autowired
private ApplicationContext applicationContext;
@Override
protected void executeInternal(JobExecutionContext jobexecutioncontext) throws JobExecutionException {
// use JobDetailImpl replace JobDetail for get jobName
JobDetailImpl jobDetail = (JobDetailImpl) jobexecutioncontext.getJobDetail();
String name = jobDetail.getName();
if (StringUtils.isEmpty(name)) {
throw new JobExecutionException("can not find service info, because desription is empty");
}
String[] serviceInfo = name.split("//.");
// serviceInfo[0] is JOB_NAME_PREFIX
String beanName = serviceInfo[1];
String methodName = serviceInfo[2];
Object serviceImpl = applicationContext.getBean(beanName);
JobDataMap dataMap = jobDetail.getJobDataMap();
Method method;
try {
Class<?> clazz = serviceImpl.getClass();
Method[] methods = clazz.getDeclaredMethods();
Class<?>[] parameterTypes = null;
for (Method n : methods) {
if (methodName.equals(n.getName())) {
parameterTypes = n.getParameterTypes();
}
}
Object[] array = parameterTypeConvert(parameterTypes, dataMap.get("data"));
method = serviceImpl.getClass().getMethod(methodName, parameterTypes);
logger.info("dynamic invoke {}.{}()", serviceImpl.getClass().getName(), methodName);
System.out.println(parameterTypes[0]);
method.invoke(serviceImpl, array);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException e) {
logger.error("reflect invoke service method error", e);
}
}
private Object[] parameterTypeConvert(Class<?>[] parameterTypes, Object obj) {
Object[] temp = new Object[parameterTypes.length];
String[] array = (String[]) obj;
for (int i = 0; i < parameterTypes.length; i++) {
if (parameterTypes[i].toString().equals("class java.lang.String")) {
System.out.println("String");
temp[i] = String.valueOf(array[i]);
}
if (parameterTypes[i].toString().equals("class java.lang.Integer")) {
System.out.println("Integer");
temp[i] = Integer.valueOf(array[i]);
}
if (parameterTypes[i].toString().equals("class java.lang.Double")) {
System.out.println("Double");
temp[i] = Double.valueOf(array[i]);
}
}
return temp;
}
}
AddJobRequest.java
package com.itstyle.quartz.request;
public class AddJobRequest {
private String jobName;// 任务名称
private String jobGroup;// 任务分组
private String jobDescription;// 任务描述
private String cronExpression;// 执行时间
private String taskParameter;
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public String getJobGroup() {
return jobGroup;
}
public void setJobGroup(String jobGroup) {
this.jobGroup = jobGroup;
}
public String getJobDescription() {
return jobDescription;
}
public void setJobDescription(String jobDescription) {
this.jobDescription = jobDescription;
}
public String getCronExpression() {
return cronExpression;
}
public void setCronExpression(String cronExpression) {
this.cronExpression = cronExpression;
}
public String getTaskParameter() {
return taskParameter;
}
public void setTaskParameter(String taskParameter) {
this.taskParameter = taskParameter;
}
}
FindAllJobRequest.java
package com.itstyle.quartz.request;
public class FindAllJobRequest {
private Integer pageSize;
private Integer pageNo;
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getPageNo() {
return pageNo;
}
public void setPageNo(Integer pageNo) {
this.pageNo = pageNo;
}
}
PauseAndResumeRequest.java
package com.itstyle.quartz.request;
public class PauseAndResumeRequest {
private String jobName;// 任务名称
private String jobGroup;// 任务分组
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public String getJobGroup() {
return jobGroup;
}
public void setJobGroup(String jobGroup) {
this.jobGroup = jobGroup;
}
}
RemoveJobRequest.java
package com.itstyle.quartz.request;
public class RemoveJobRequest {
private String jobName;
private String jobGroup;
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public String getJobGroup() {
return jobGroup;
}
public void setJobGroup(String jobGroup) {
this.jobGroup = jobGroup;
}
}
TriggerRequest.java
package com.itstyle.quartz.request;
public class TriggerRequest {
private String jobName;
private String jobGroup;
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public String getJobGroup() {
return jobGroup;
}
public void setJobGroup(String jobGroup) {
this.jobGroup = jobGroup;
}
}
HelloService.java
package com.itstyle.quartz.service;
import org.springframework.stereotype.Service;
@Service
public class HelloService {
public void sayHello(String aa, Integer bb) {
System.out.format("%s %d", aa, bb);
}
}
JobController.java
package com.itstyle.quartz.web;
import javax.annotation.Resource;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.itstyle.quartz.dynamicquery.Service.QuartzConfigService;
import com.itstyle.quartz.entity.ResponseData;
import com.itstyle.quartz.request.AddJobRequest;
import com.itstyle.quartz.request.FindAllJobRequest;
import com.itstyle.quartz.request.PauseAndResumeRequest;
import com.itstyle.quartz.request.RemoveJobRequest;
import com.itstyle.quartz.request.TriggerRequest;
@RestController
public class JobController {
private final static Logger LOGGER = LoggerFactory.getLogger(JobController.class);
@Resource
Scheduler scheduler;
@Resource
QuartzConfigService quartzConfigService;
@Resource
JobService jobService;
@PostMapping("/add")
public ResponseEntity<?> addJob(@RequestBody AddJobRequest req) throws Exception {
LOGGER.info("add quartz job");
String result = jobService.addjob(req.getJobName(), req.getJobGroup(), req.getCronExpression(),
req.getJobDescription(), req.getTaskParameter());
return ResponseData.ok(result);
}
@PostMapping("/list")
public ResponseEntity<?> findAllJob(@RequestBody FindAllJobRequest req) {
LOGGER.info("任务列表");
Page page = quartzConfigService.findAll(PageRequest.of(req.getPageNo(), req.getPageSize()));
return ResponseData.ok(page);
}
@PostMapping("/trigger")
public ResponseEntity<?> trigger(@RequestBody TriggerRequest req) throws Exception {
LOGGER.info("触发任务");
String result = jobService.triggerJob(req.getJobName(), req.getJobGroup());
return ResponseData.ok(result);
}
@PostMapping("/remove")
public ResponseEntity<?> remove(@RequestBody RemoveJobRequest req) throws SchedulerException {
LOGGER.info("移除任务");
String result = jobService.deleteJob(req.getJobName(), req.getJobGroup());
return ResponseData.ok(result);
}
@PostMapping("/pause")
public ResponseEntity<?> pause(@RequestBody PauseAndResumeRequest req) throws SchedulerException {
LOGGER.info("停止任务");
String result = jobService.pause(req.getJobName(), req.getJobGroup());
return ResponseData.ok(result);
}
@PostMapping("/resume")
public ResponseEntity<?> resume(@RequestBody PauseAndResumeRequest req) throws SchedulerException {
LOGGER.info("恢复任务");
String result = jobService.resume(req.getJobName(), req.getJobGroup());
return ResponseData.ok(result);
}
}
JobService.java
package com.itstyle.quartz.web;
import java.security.Principal;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;
import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.itstyle.quartz.dynamicquery.Service.QuartzConfigService;
import com.itstyle.quartz.entity.QuartzConfigModel;
import com.itstyle.quartz.entity.identity.QuartzConfigIdentity;
@Service
@SuppressWarnings("all")
public class JobService {
private final Logger logger = LoggerFactory.getLogger(getClass());
private final String JOBCLASSNAME = "com.itstyle.quartz.job.DynamicQuartzJob";
private final Integer VALID = 0;
private final Integer INVALID = 1;
@Resource
ApplicationContext applicationContext;
@Resource
Scheduler scheduler;
@Resource
QuartzConfigService quartzConfigService;
@Transactional
public String pause(String jobName, String jobGroup) throws SchedulerException {
JobKey key = new JobKey(jobName, jobGroup);
if (scheduler.checkExists(key)) {
scheduler.pauseJob(key);
QuartzConfigModel quartzConfigModel = quartzConfigService
.findOne(new QuartzConfigIdentity(jobName, jobGroup));
quartzConfigModel.setJobStatus(INVALID);
quartzConfigService.save(quartzConfigModel);
return "ok";
} else {
return "任务不存在";
}
}
@Transactional
public String resume(String jobName, String jobGroup) throws SchedulerException {
JobKey key = new JobKey(jobName, jobGroup);
if (scheduler.checkExists(key)) {
scheduler.resumeJob(key);
QuartzConfigModel quartzConfigModel = quartzConfigService
.findOne(new QuartzConfigIdentity(jobName, jobGroup));
quartzConfigModel.setJobStatus(VALID);
quartzConfigService.save(quartzConfigModel);
return "ok";
} else {
return "任务不存在";
}
}
public String triggerJob(String jobName, String jobGroup) throws Exception {
JobKey jobKey = new JobKey(jobName, jobGroup);
if (scheduler.checkExists(jobKey)) {
scheduler.triggerJob(jobKey);
return "ok";
} else {
return "任務不存在";
}
}
@Transactional
public String addjob(String jobName, String jobGroup, String cronExpression, String jobDescription,
String taskParameter) throws Exception {
JobKey jobKey = new JobKey(jobName, jobGroup);
boolean isExists = scheduler.checkExists(jobKey);
if (isExists) {
return "已存在";
}
startJob(jobName, jobGroup, jobDescription, taskParameter, cronExpression);
saveQuartzConfigMoel(jobName, jobGroup, cronExpression, jobDescription, taskParameter);
return null;
}
@Transactional
public String deleteJob(String jobName, String jobGroup) throws SchedulerException {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
// ‘停止触发器
if (scheduler.checkExists(triggerKey)) {
scheduler.pauseTrigger(triggerKey);
// ’ 移除触发器
scheduler.unscheduleJob(triggerKey);
}
JobKey jobKey = new JobKey(jobName, jobGroup);
if (scheduler.checkExists(jobKey)) {
// ‘删除任务
scheduler.deleteJob(jobKey);
quartzConfigService.delete(new QuartzConfigIdentity(jobName, jobGroup));
return "ok";
} else {
return "任务不存在";
}
}
public void startJob(String jobName, String jobGroup, String description, String taskParameter,
String cronExpression) throws Exception {
Class cls = Class.forName(JOBCLASSNAME);
cls.newInstance();
JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, jobGroup).withDescription(description)
.build();
jobDetail.getJobDataMap().put("data", taskParameter.split(","));
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroup).startNow()
.withSchedule(cronScheduleBuilder).build();
scheduler.scheduleJob(jobDetail, trigger);
}
private void saveQuartzConfigMoel(String jobName, String jobGroup, String cronExpression, String jobDescription,
String taskParameter) {
QuartzConfigModel quartzConfigModel = new QuartzConfigModel();
QuartzConfigIdentity id = new QuartzConfigIdentity(jobName, jobGroup);
quartzConfigModel.setId(id);
quartzConfigModel.setCronExpression(cronExpression);
quartzConfigModel.setJobDescription(jobDescription);
quartzConfigModel.setTaskParameter(taskParameter);
HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
quartzConfigModel.setCreateUser(getHttpRequestUserGid(req));
quartzConfigService.save(quartzConfigModel);
}
/**
* 获取token中的用户
*
* @param request HttpServletRequest情報
* @return
*/
private String getHttpRequestUserGid(HttpServletRequest request) {
Principal principal = request.getUserPrincipal();
if (principal == null) {
return "";
} else {
String userName = principal.getName();
if (userName != null && userName.indexOf("@") > 0) {
return userName.split("@")[0];
} else {
return userName;
}
}
}
}
DateToCronUtil.java
//转化date到cron
package com.itstyle.quartz;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.quartz.CronExpression;
public class DateToCronUtil {
private static final String DATEFORMAT = "ss mm HH dd MM ? yyyy";
/***
*
* @param date
* @param dateFormat : e.g:yyyy-MM-dd HH:mm:ss
* @return
* @throws ParseException
*/
public static String formatDateByPattern(Date date, String dateFormat) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
String formatTimeStr = null;
if (date != null) {
formatTimeStr = sdf.format(date);
}
if (checkCronValid(formatTimeStr, date)) {
return formatTimeStr;
} else {
return "输入有效日期";
}
}
/***
* convert Date to cron ,eg. "0 06 10 15 1 ? 2014"
*
* @param date : 时间点
* @return
* @throws ParseException
*/
public static String getCron(Date date) throws ParseException {
return formatDateByPattern(date, DATEFORMAT);
}
/**
* 验证是否有效的cron表达式
*
* @param cron
* @param date
* @throws ParseException
*/
private static boolean checkCronValid(String cron, Date date) throws ParseException {
CronExpression cronExpression = new CronExpression(cron);
return cronExpression.isSatisfiedBy(date);
}
// public static void main(String[] args) throws ParseException {
// System.out.println(getCron(new Date()));
// }
}
========================================博客园对于代码块中的文字不算字数====================================================================
========================================博客园对于代码块中的文字不算字数====================================================================
========================================博客园对于代码块中的文字不算字数====================================================================
========================================博客园对于代码块中的文字不算字数====================================================================
========================================博客园对于代码块中的文字不算字数====================================================================
========================================博客园对于代码块中的文字不算字数====================================================================
========================================博客园对于代码块中的文字不算字数====================================================================
========================================博客园对于代码块中的文字不算字数====================================================================
========================================博客园对于代码块中的文字不算字数====================================================================
========================================博客园对于代码块中的文字不算字数====================================================================
========================================博客园对于代码块中的文字不算字数====================================================================
========================================博客园对于代码块中的文字不算字数====================================================================
========================================博客园对于代码块中的文字不算字数====================================================================
========================================博客园对于代码块中的文字不算字数====================================================================
========================================博客园对于代码块中的文字不算字数====================================================================
========================================博客园对于代码块中的文字不算字数====================================================================
========================================博客园对于代码块中的文字不算字数====================================================================