程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

springboot+quertz实现动态任务调度

发布于2021-05-29 23:09     阅读(863)     评论(0)     点赞(4)     收藏(1)


1.maven pom引入依赖

  1. <!--quartz-->
  2. <dependency>
  3. <groupId>org.quartz-scheduler</groupId>
  4. <artifactId>quartz</artifactId>
  5. <version>2.2.3</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.quartz-scheduler</groupId>
  9. <artifactId>quartz-jobs</artifactId>
  10. <version>2.2.3</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.springframework</groupId>
  14. <artifactId>spring-context-support</artifactId>
  15. </dependency>

2.数据库建立quartz相关表

执行quartz建表sql即可。

3.quartz配置文件quartz.properties

  1. # Default Properties file for use by StdSchedulerFactory
  2. # to create a Quartz Scheduler Instance, if a different
  3. # properties file is not explicitly specified.
  4. #
  5. org.quartz.scheduler.instanceName: DefaultQuartzScheduler
  6. #如果使用集群,instanceId必须唯一,设置成AUTO
  7. org.quartz.scheduler.instanceId = AUTO
  8. org.quartz.scheduler.rmi.export: false
  9. org.quartz.scheduler.rmi.proxy: false
  10. org.quartz.scheduler.wrapJobExecutionInUserTransaction: false
  11. org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
  12. org.quartz.threadPool.threadCount: 50
  13. org.quartz.threadPool.threadPriority: 5
  14. org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true
  15. org.quartz.jobStore.misfireThreshold: 60000
  16. #============================================================================
  17. # Configure JobStore
  18. #============================================================================
  19. #
  20. #org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
  21. #存储方式使用JobStoreTX,也就是数据库
  22. org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX
  23. org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
  24. org.quartz.jobStore.useProperties:false
  25. #数据库中quartz表的表名前缀
  26. org.quartz.jobStore.tablePrefix:QRTZ_
  27. org.quartz.jobStore.dataSource:qzDS
  28. #是否使用集群(如果项目只部署到 一台服务器,就不用了)
  29. org.quartz.jobStore.isClustered = true
  30. org.quartz.jobStore.clusterCheckinInterval = 30000
  31. #============================================================================
  32. # Configure Datasources
  33. #============================================================================
  34. #配置数据源
  35. org.quartz.dataSource.qzDS.driver:com.mysql.cj.jdbc.Driver
  36. org.quartz.dataSource.qzDS.URL:jdbc:mysql://localhost:3306/micro_mall?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false
  37. org.quartz.dataSource.qzDS.user:root
  38. org.quartz.dataSource.qzDS.password:`1qazx
  39. org.quartz.dataSource.qzDS.validationQuery=select 0 from dual

此处需说明:org.quartz.jobStore.userProperties值为true时,标记指示着持久性 JobStore 所有在 JobDataMap 中的值都是字符串,因此能以 名-值 对的形式存储,而不用让更复杂的对象以序列化的形式存入 BLOB 列中。

job工厂:

  1. import org.quartz.spi.TriggerFiredBundle;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
  4. import org.springframework.scheduling.quartz.AdaptableJobFactory;
  5. import org.springframework.stereotype.Component;
  6. @Component
  7. public class SpringJobFactory extends AdaptableJobFactory {
  8. @Autowired
  9. private AutowireCapableBeanFactory capableBeanFactory;
  10. @Override
  11. protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
  12. Object jobInstance = super.createJobInstance(bundle);
  13. capableBeanFactory.autowireBean(jobInstance);
  14. return jobInstance;
  15. }
  16. }

定时任务配置:

  1. package com.hxkg.datafusion.schedule;
  2. import org.quartz.Scheduler;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.beans.factory.config.PropertiesFactoryBean;
  5. import org.springframework.context.annotation.Bean;
  6. import org.springframework.context.annotation.Configuration;
  7. import org.springframework.core.io.ClassPathResource;
  8. import org.springframework.scheduling.quartz.SchedulerFactoryBean;
  9. import java.io.IOException;
  10. import java.util.Properties;
  11. /**
  12. * 定时任务配置
  13. *
  14. * @author yangfeng
  15. * @date 2018-07-03
  16. */
  17. @Configuration
  18. public class QuartzConfig {
  19. @Autowired
  20. private SpringJobFactory springJobFactory;
  21. @Bean
  22. public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
  23. //获取配置属性
  24. PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
  25. propertiesFactoryBean.setLocation(new ClassPathResource("quartz.properties"));
  26. //在quartz.properties中的属性被读取并注入后再初始化对象
  27. propertiesFactoryBean.afterPropertiesSet();
  28. //创建SchedulerFactoryBean
  29. SchedulerFactoryBean factory = new SchedulerFactoryBean();
  30. Properties pro = propertiesFactoryBean.getObject();
  31. factory.setOverwriteExistingJobs(true);
  32. factory.setAutoStartup(true);
  33. factory.setQuartzProperties(pro);
  34. factory.setJobFactory(springJobFactory);
  35. return factory;
  36. }
  37. @Bean
  38. public Scheduler scheduler() throws IOException{
  39. return schedulerFactoryBean().getScheduler();
  40. }
  41. }

4.任务调度表结构

  1. CREATE TABLE `schedule_job` (
  2. `id` varchar(32) NOT NULL,
  3. `job_name` varchar(126) NOT NULL COMMENT '任务名称',
  4. `bean_name` varchar(126) NOT NULL COMMENT 'bean名称',
  5. `cron_expression` varchar(126) NOT NULL COMMENT '表达式',
  6. `method_name` varchar(32) DEFAULT NULL COMMENT '方法名',
  7. `params` varchar(32) DEFAULT NULL COMMENT '参数',
  8. `status` int(1) DEFAULT NULL,
  9. `create_time` datetime DEFAULT NULL,
  10. `createBy` varchar(32) DEFAULT NULL,
  11. PRIMARY KEY (`id`)
  12. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='任务调度表';

5.任务调度实体

  1. package com.mall.shop.entity.gen;
  2. import java.io.Serializable;
  3. import java.util.Date;
  4. public class ScheduleJob implements Serializable {
  5. /**
  6. * This field was generated by MyBatis Generator.
  7. * This field corresponds to the database column schedule_job.id
  8. *
  9. * @mbggenerated
  10. */
  11. private String id;
  12. /**
  13. * This field was generated by MyBatis Generator.
  14. * This field corresponds to the database column schedule_job.job_name
  15. *
  16. * @mbggenerated
  17. */
  18. private String jobName;
  19. /**
  20. * This field was generated by MyBatis Generator.
  21. * This field corresponds to the database column schedule_job.bean_name
  22. *
  23. * @mbggenerated
  24. */
  25. private String beanName;
  26. /**
  27. * This field was generated by MyBatis Generator.
  28. * This field corresponds to the database column schedule_job.cron_expression
  29. *
  30. * @mbggenerated
  31. */
  32. private String cronExpression;
  33. /**
  34. * This field was generated by MyBatis Generator.
  35. * This field corresponds to the database column schedule_job.method_name
  36. *
  37. * @mbggenerated
  38. */
  39. private String methodName;
  40. /**
  41. * This field was generated by MyBatis Generator.
  42. * This field corresponds to the database column schedule_job.params
  43. *
  44. * @mbggenerated
  45. */
  46. private String params;
  47. /**
  48. * This field was generated by MyBatis Generator.
  49. * This field corresponds to the database column schedule_job.status
  50. *
  51. * @mbggenerated
  52. */
  53. private Integer status;
  54. /**
  55. * This field was generated by MyBatis Generator.
  56. * This field corresponds to the database column schedule_job.create_time
  57. *
  58. * @mbggenerated
  59. */
  60. private Date createTime;
  61. /**
  62. * This field was generated by MyBatis Generator.
  63. * This field corresponds to the database column schedule_job.createBy
  64. *
  65. * @mbggenerated
  66. */
  67. private String createby;
  68. /**
  69. * This field was generated by MyBatis Generator.
  70. * This field corresponds to the database table schedule_job
  71. *
  72. * @mbggenerated
  73. */
  74. private static final long serialVersionUID = 1L;
  75. /**
  76. * This method was generated by MyBatis Generator.
  77. * This method returns the value of the database column schedule_job.id
  78. *
  79. * @return the value of schedule_job.id
  80. *
  81. * @mbggenerated
  82. */
  83. public String getId() {
  84. return id;
  85. }
  86. /**
  87. * This method was generated by MyBatis Generator.
  88. * This method sets the value of the database column schedule_job.id
  89. *
  90. * @param id the value for schedule_job.id
  91. *
  92. * @mbggenerated
  93. */
  94. public void setId(String id) {
  95. this.id = id;
  96. }
  97. /**
  98. * This method was generated by MyBatis Generator.
  99. * This method returns the value of the database column schedule_job.job_name
  100. *
  101. * @return the value of schedule_job.job_name
  102. *
  103. * @mbggenerated
  104. */
  105. public String getJobName() {
  106. return jobName;
  107. }
  108. /**
  109. * This method was generated by MyBatis Generator.
  110. * This method sets the value of the database column schedule_job.job_name
  111. *
  112. * @param jobName the value for schedule_job.job_name
  113. *
  114. * @mbggenerated
  115. */
  116. public void setJobName(String jobName) {
  117. this.jobName = jobName == null ? null : jobName.trim();
  118. }
  119. /**
  120. * This method was generated by MyBatis Generator.
  121. * This method returns the value of the database column schedule_job.bean_name
  122. *
  123. * @return the value of schedule_job.bean_name
  124. *
  125. * @mbggenerated
  126. */
  127. public String getBeanName() {
  128. return beanName;
  129. }
  130. /**
  131. * This method was generated by MyBatis Generator.
  132. * This method sets the value of the database column schedule_job.bean_name
  133. *
  134. * @param beanName the value for schedule_job.bean_name
  135. *
  136. * @mbggenerated
  137. */
  138. public void setBeanName(String beanName) {
  139. this.beanName = beanName == null ? null : beanName.trim();
  140. }
  141. /**
  142. * This method was generated by MyBatis Generator.
  143. * This method returns the value of the database column schedule_job.cron_expression
  144. *
  145. * @return the value of schedule_job.cron_expression
  146. *
  147. * @mbggenerated
  148. */
  149. public String getCronExpression() {
  150. return cronExpression;
  151. }
  152. /**
  153. * This method was generated by MyBatis Generator.
  154. * This method sets the value of the database column schedule_job.cron_expression
  155. *
  156. * @param cronExpression the value for schedule_job.cron_expression
  157. *
  158. * @mbggenerated
  159. */
  160. public void setCronExpression(String cronExpression) {
  161. this.cronExpression = cronExpression == null ? null : cronExpression.trim();
  162. }
  163. /**
  164. * This method was generated by MyBatis Generator.
  165. * This method returns the value of the database column schedule_job.method_name
  166. *
  167. * @return the value of schedule_job.method_name
  168. *
  169. * @mbggenerated
  170. */
  171. public String getMethodName() {
  172. return methodName;
  173. }
  174. /**
  175. * This method was generated by MyBatis Generator.
  176. * This method sets the value of the database column schedule_job.method_name
  177. *
  178. * @param methodName the value for schedule_job.method_name
  179. *
  180. * @mbggenerated
  181. */
  182. public void setMethodName(String methodName) {
  183. this.methodName = methodName == null ? null : methodName.trim();
  184. }
  185. /**
  186. * This method was generated by MyBatis Generator.
  187. * This method returns the value of the database column schedule_job.params
  188. *
  189. * @return the value of schedule_job.params
  190. *
  191. * @mbggenerated
  192. */
  193. public String getParams() {
  194. return params;
  195. }
  196. /**
  197. * This method was generated by MyBatis Generator.
  198. * This method sets the value of the database column schedule_job.params
  199. *
  200. * @param params the value for schedule_job.params
  201. *
  202. * @mbggenerated
  203. */
  204. public void setParams(String params) {
  205. this.params = params == null ? null : params.trim();
  206. }
  207. /**
  208. * This method was generated by MyBatis Generator.
  209. * This method returns the value of the database column schedule_job.status
  210. *
  211. * @return the value of schedule_job.status
  212. *
  213. * @mbggenerated
  214. */
  215. public Integer getStatus() {
  216. return status;
  217. }
  218. /**
  219. * This method was generated by MyBatis Generator.
  220. * This method sets the value of the database column schedule_job.status
  221. *
  222. * @param status the value for schedule_job.status
  223. *
  224. * @mbggenerated
  225. */
  226. public void setStatus(Integer status) {
  227. this.status = status;
  228. }
  229. /**
  230. * This method was generated by MyBatis Generator.
  231. * This method returns the value of the database column schedule_job.create_time
  232. *
  233. * @return the value of schedule_job.create_time
  234. *
  235. * @mbggenerated
  236. */
  237. public Date getCreateTime() {
  238. return createTime;
  239. }
  240. /**
  241. * This method was generated by MyBatis Generator.
  242. * This method sets the value of the database column schedule_job.create_time
  243. *
  244. * @param createTime the value for schedule_job.create_time
  245. *
  246. * @mbggenerated
  247. */
  248. public void setCreateTime(Date createTime) {
  249. this.createTime = createTime;
  250. }
  251. /**
  252. * This method was generated by MyBatis Generator.
  253. * This method returns the value of the database column schedule_job.createBy
  254. *
  255. * @return the value of schedule_job.createBy
  256. *
  257. * @mbggenerated
  258. */
  259. public String getCreateby() {
  260. return createby;
  261. }
  262. /**
  263. * This method was generated by MyBatis Generator.
  264. * This method sets the value of the database column schedule_job.createBy
  265. *
  266. * @param createby the value for schedule_job.createBy
  267. *
  268. * @mbggenerated
  269. */
  270. public void setCreateby(String createby) {
  271. this.createby = createby == null ? null : createby.trim();
  272. }
  273. }

实体扩展类:

  1. package com.mall.shop.entity.customized;
  2. import java.io.Serializable;
  3. import com.mall.shop.entity.gen.ScheduleJob;
  4. import org.apache.commons.lang3.builder.ToStringBuilder;
  5. import org.apache.commons.lang3.builder.ToStringStyle;
  6. import org.codehaus.jackson.map.annotate.JsonSerialize;
  7. import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
  8. /**
  9. * 应用对象 - ScheduleJob.
  10. * <p>
  11. * 该类于 2021-05-21 13:56:38 首次生成,后由开发手工维护。
  12. * </p>
  13. * @author yangfeng
  14. * @version 1.0.0, May 21, 2021
  15. */
  16. @JsonSerialize(include = Inclusion.ALWAYS)
  17. public final class ScheduleJobAO extends ScheduleJob implements Serializable {
  18. /**
  19. * 默认的序列化 id.
  20. */
  21. private static final long serialVersionUID = 1L;
  22. @Override
  23. public String toString() {
  24. return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
  25. }
  26. }

6.接口服务

  1. package com.mall.shop.service;
  2. import com.backstage.core.result.ServiceResult;
  3. import com.backstage.core.service.IBaseAOService;
  4. import com.mall.shop.dto.request.ScheduleJobRequest;
  5. import com.mall.shop.entity.customized.ScheduleJobAO;
  6. import com.mall.shop.entity.gen.ScheduleJobCriteria;
  7. import java.util.List;
  8. public interface IScheduleJobService extends IBaseAOService<ScheduleJobAO, ScheduleJobCriteria> {
  9. ServiceResult<List<ScheduleJobAO>> list(ScheduleJobRequest request);
  10. ServiceResult<List<ScheduleJobAO>> listByCondition(ScheduleJobRequest request);
  11. ServiceResult<Boolean> add(ScheduleJobAO scheduleJob);
  12. ServiceResult<Boolean> update(ScheduleJobAO scheduleJob);
  13. ServiceResult<Boolean> deleteBatch(String[] jobIds);
  14. ServiceResult<Boolean> run(String[] jobIds);
  15. ServiceResult<Boolean> pause(String[] jobIds);
  16. ServiceResult<Boolean> resume(String[] jobIds);
  17. }
  1. package com.mall.shop.service.impl;
  2. import com.backstage.common.page.Page;
  3. import com.backstage.core.mapper.BaseGeneratedMapper;
  4. import com.backstage.core.result.ServiceResult;
  5. import com.backstage.core.result.ServiceResultHelper;
  6. import com.backstage.core.service.AbstractBaseAOService;
  7. import com.github.pagehelper.PageHelper;
  8. import com.github.pagehelper.PageInfo;
  9. import com.mall.shop.dao.customized.ScheduleJobCustomizedMapper;
  10. import com.mall.shop.dao.gen.ScheduleJobGeneratedMapper;
  11. import com.mall.shop.dto.request.ScheduleJobRequest;
  12. import com.mall.shop.entity.customized.ScheduleJobAO;
  13. import com.mall.shop.entity.gen.ScheduleJob;
  14. import com.mall.shop.entity.gen.ScheduleJobCriteria;
  15. import com.mall.shop.enums.ScheduleStatus;
  16. import com.mall.shop.service.IScheduleJobService;
  17. import com.mall.shop.util.ScheduleUtils;
  18. import org.quartz.CronTrigger;
  19. import org.quartz.Scheduler;
  20. import org.springframework.beans.factory.annotation.Autowired;
  21. import org.springframework.stereotype.Service;
  22. import org.springframework.transaction.annotation.Transactional;
  23. import javax.annotation.PostConstruct;
  24. import javax.annotation.Resource;
  25. import java.util.Date;
  26. import java.util.List;
  27. import java.util.Map;
  28. /**
  29. * 任务调度服务
  30. *
  31. * @author yangfeng
  32. */
  33. @Service
  34. public class ScheduleJobService extends AbstractBaseAOService<ScheduleJobAO, ScheduleJobCriteria> implements IScheduleJobService {
  35. @Resource
  36. private ScheduleJobGeneratedMapper scheduleJobGeneratedMapper;
  37. @Resource
  38. private ScheduleJobCustomizedMapper scheduleJobCustomizedMapper;
  39. @Override
  40. protected BaseGeneratedMapper<ScheduleJobAO, ScheduleJobCriteria> getGeneratedMapper() {
  41. return scheduleJobGeneratedMapper;
  42. }
  43. @Autowired
  44. private Scheduler scheduler;
  45. /**
  46. * 项目启动时,初始化定时器
  47. */
  48. @PostConstruct
  49. public void init() {
  50. List<ScheduleJobAO> scheduleJobList = this.listByCondition(null).getData();
  51. for (ScheduleJobAO scheduleJob : scheduleJobList) {
  52. CronTrigger cronTrigger = ScheduleUtils.getCronTrigger(scheduler, scheduleJob.getId());
  53. //如果不存在,则创建
  54. if (cronTrigger == null) {
  55. ScheduleUtils.createScheduleJob(scheduler, scheduleJob);
  56. } else {
  57. ScheduleUtils.updateScheduleJob(scheduler, scheduleJob);
  58. }
  59. }
  60. }
  61. /**
  62. * 分页查询
  63. *
  64. * @param request
  65. * @return
  66. */
  67. @Override
  68. public ServiceResult<List<ScheduleJobAO>> list(ScheduleJobRequest request) {
  69. ServiceResult<List<ScheduleJobAO>> ret = new ServiceResult();
  70. PageHelper.startPage(request.getPageNo(), request.getPageSize());
  71. List<ScheduleJobAO> scheduleJobAOList = scheduleJobCustomizedMapper.listByCondition(request);
  72. ret.setData(scheduleJobAOList);
  73. ret.setSucceed(true);
  74. ret.setAdditionalProperties("page", Page.obtainPage(new PageInfo(scheduleJobAOList)));
  75. return ret;
  76. }
  77. @Override
  78. public ServiceResult<List<ScheduleJobAO>> listByCondition(ScheduleJobRequest request) {
  79. return ServiceResultHelper.genResultWithSuccess(scheduleJobCustomizedMapper.listByCondition(request));
  80. }
  81. @Override
  82. @Transactional(rollbackFor = Exception.class)
  83. public ServiceResult<Boolean> add(ScheduleJobAO scheduleJob) {
  84. scheduleJob.setCreateTime(new Date());
  85. scheduleJob.setStatus(ScheduleStatus.NORMAL.getValue());
  86. this.insert(scheduleJob);
  87. ScheduleUtils.createScheduleJob(scheduler, scheduleJob);
  88. return ServiceResultHelper.genResultWithSuccess();
  89. }
  90. @Override
  91. @Transactional(rollbackFor = Exception.class)
  92. public ServiceResult<Boolean> update(ScheduleJobAO scheduleJob) {
  93. ScheduleUtils.updateScheduleJob(scheduler, scheduleJob);
  94. this.saveOrUpdate(scheduleJob);
  95. return ServiceResultHelper.genResultWithSuccess();
  96. }
  97. @Override
  98. @Transactional(rollbackFor = Exception.class)
  99. public ServiceResult<Boolean> deleteBatch(String[] jobIds) {
  100. for (String jobId : jobIds) {
  101. ScheduleUtils.deleteScheduleJob(scheduler, jobId);
  102. deleteById(jobId);
  103. }
  104. return ServiceResultHelper.genResultWithSuccess();
  105. }
  106. @Override
  107. @Transactional(rollbackFor = Exception.class)
  108. public ServiceResult<Boolean> run(String[] jobIds) {
  109. for (String jobId : jobIds) {
  110. ScheduleUtils.run(scheduler, selectByPrimaryKey(jobId).getData());
  111. }
  112. return ServiceResultHelper.genResultWithSuccess();
  113. }
  114. @Override
  115. @Transactional(rollbackFor = Exception.class)
  116. public ServiceResult<Boolean> pause(String[] jobIds) {
  117. for (String jobId : jobIds) {
  118. ScheduleUtils.pauseJob(scheduler, jobId);
  119. }
  120. return updateBatch(jobIds, ScheduleStatus.PAUSE.getValue());
  121. }
  122. @Override
  123. @Transactional(rollbackFor = Exception.class)
  124. public ServiceResult<Boolean> resume(String[] jobIds) {
  125. for (String jobId : jobIds) {
  126. ScheduleUtils.resumeJob(scheduler, jobId);
  127. }
  128. return updateBatch(jobIds, ScheduleStatus.NORMAL.getValue());
  129. }
  130. public ServiceResult<Boolean> updateBatch(String[] jobIds, int status) {
  131. for (String jobId : jobIds) {
  132. ScheduleJobAO scheduleJob = new ScheduleJobAO();
  133. scheduleJob.setId(jobId);
  134. scheduleJob.setStatus(status);
  135. this.saveOrUpdate(scheduleJob);
  136. }
  137. return ServiceResultHelper.genResultWithSuccess();
  138. }
  139. }
  1. 7.动态调度相关
  2. ScheduleUtils工具类:
  1. package com.mall.shop.util;
  2. import com.backstage.common.exception.BaseException;
  3. import com.mall.shop.entity.customized.ScheduleJobAO;
  4. import com.mall.shop.entity.gen.ScheduleJob;
  5. import com.mall.shop.enums.ScheduleStatus;
  6. import org.quartz.*;
  7. /**
  8. * 定时任务工具类
  9. *
  10. */
  11. public class ScheduleUtils {
  12. private final static String JOB_NAME = "TASK_";
  13. /**
  14. * 任务调度参数key
  15. */
  16. public static final String JOB_PARAM_KEY = "JOB_PARAM_KEY";
  17. /**
  18. * 获取触发器key
  19. */
  20. public static TriggerKey getTriggerKey(String jobId) {
  21. return TriggerKey.triggerKey(JOB_NAME + jobId);
  22. }
  23. /**
  24. * 获取jobKey
  25. */
  26. public static JobKey getJobKey(String jobId) {
  27. return JobKey.jobKey(JOB_NAME + jobId);
  28. }
  29. /**
  30. * 获取表达式触发器
  31. */
  32. public static CronTrigger getCronTrigger(Scheduler scheduler, String jobId) {
  33. try {
  34. return (CronTrigger) scheduler.getTrigger(getTriggerKey(jobId));
  35. } catch (SchedulerException e) {
  36. throw new BaseException(-1, "获取定时任务CronTrigger出现异常" + e.getMessage());
  37. }
  38. }
  39. /**
  40. * 创建定时任务
  41. */
  42. public static void createScheduleJob(Scheduler scheduler, ScheduleJobAO scheduleJob) {
  43. try {
  44. //构建job信息
  45. JobDetail jobDetail = JobBuilder.newJob(ScheduleJobExec.class).withIdentity(getJobKey(scheduleJob.getId())).build();
  46. //表达式调度构建器
  47. CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())
  48. .withMisfireHandlingInstructionDoNothing();
  49. //按新的cronExpression表达式构建一个新的trigger
  50. CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(scheduleJob.getId())).withSchedule(scheduleBuilder).build();
  51. //放入参数,运行时的方法可以获取
  52. jobDetail.getJobDataMap().put(JOB_PARAM_KEY, scheduleJob);
  53. scheduler.scheduleJob(jobDetail, trigger);
  54. //暂停任务
  55. if (scheduleJob.getStatus() == ScheduleStatus.PAUSE.getValue()) {
  56. pauseJob(scheduler, scheduleJob.getId());
  57. }
  58. } catch (SchedulerException e) {
  59. throw new BaseException(-1, "创建定时任务失败" + e.getMessage());
  60. }
  61. }
  62. /**
  63. * 更新定时任务
  64. */
  65. public static void updateScheduleJob(Scheduler scheduler, ScheduleJobAO scheduleJob) {
  66. try {
  67. TriggerKey triggerKey = getTriggerKey(scheduleJob.getId());
  68. //表达式调度构建器
  69. CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())
  70. .withMisfireHandlingInstructionDoNothing();
  71. CronTrigger trigger = getCronTrigger(scheduler, scheduleJob.getId());
  72. //按新的cronExpression表达式重新构建trigger
  73. trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
  74. //参数
  75. trigger.getJobDataMap().put(JOB_PARAM_KEY, scheduleJob);
  76. scheduler.rescheduleJob(triggerKey, trigger);
  77. //暂停任务
  78. if (scheduleJob.getStatus() == ScheduleStatus.PAUSE.getValue()) {
  79. pauseJob(scheduler, scheduleJob.getId());
  80. }
  81. } catch (SchedulerException e) {
  82. throw new BaseException(-1, "更新定时任务失败" + e.getMessage());
  83. }
  84. }
  85. /**
  86. * 立即执行任务
  87. */
  88. public static void run(Scheduler scheduler, ScheduleJobAO scheduleJob) {
  89. try {
  90. //参数
  91. JobDataMap dataMap = new JobDataMap();
  92. dataMap.put(JOB_PARAM_KEY, scheduleJob);
  93. scheduler.triggerJob(getJobKey(scheduleJob.getId()), dataMap);
  94. } catch (SchedulerException e) {
  95. throw new BaseException(-1, "立即执行定时任务失败" + e.getMessage());
  96. }
  97. }
  98. /**
  99. * 暂停任务
  100. */
  101. public static void pauseJob(Scheduler scheduler, String jobId) {
  102. try {
  103. scheduler.pauseJob(getJobKey(jobId));
  104. } catch (SchedulerException e) {
  105. throw new BaseException(-1, "暂停定时任务失败" + e.getMessage());
  106. }
  107. }
  108. /**
  109. * 恢复任务
  110. */
  111. public static void resumeJob(Scheduler scheduler, String jobId) {
  112. try {
  113. scheduler.resumeJob(getJobKey(jobId));
  114. } catch (SchedulerException e) {
  115. throw new BaseException(-1, "恢复定时任务失败" + e.getMessage());
  116. }
  117. }
  118. /**
  119. * 删除定时任务
  120. */
  121. public static void deleteScheduleJob(Scheduler scheduler, String jobId) {
  122. try {
  123. scheduler.deleteJob(getJobKey(jobId));
  124. } catch (SchedulerException e) {
  125. throw new BaseException(-1, "删除定时任务失败" + e.getMessage());
  126. }
  127. }
  128. }

定时任务调度类ScheduleJobExec:

  1. package com.mall.shop.util;
  2. import com.alibaba.fastjson.JSON;
  3. import com.mall.shop.entity.customized.ScheduleJobAO;
  4. import org.quartz.JobExecutionContext;
  5. import org.quartz.JobExecutionException;
  6. import org.slf4j.Logger;
  7. import org.slf4j.LoggerFactory;
  8. import org.springframework.scheduling.quartz.QuartzJobBean;
  9. import java.util.concurrent.ExecutorService;
  10. import java.util.concurrent.Executors;
  11. import java.util.concurrent.Future;
  12. /**
  13. * 定时任务
  14. */
  15. public class ScheduleJobExec extends QuartzJobBean {
  16. private Logger logger = LoggerFactory.getLogger(getClass());
  17. private ExecutorService service = Executors.newSingleThreadExecutor();
  18. @Override
  19. protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
  20. Object o = context.getMergedJobDataMap().get(ScheduleUtils.JOB_PARAM_KEY);
  21. ScheduleJobAO scheduleJob;
  22. if (o instanceof ScheduleJobAO) {
  23. scheduleJob = (ScheduleJobAO) o;
  24. } else {
  25. scheduleJob = JSON.parseObject(JSON.toJSON(o).toString(), ScheduleJobAO.class);
  26. }
  27. //任务开始时间
  28. long startTime = System.currentTimeMillis();
  29. try {
  30. //执行任务
  31. logger.info("任务准备执行,任务ID:" + scheduleJob.getId());
  32. ScheduleRunnable task = new ScheduleRunnable(scheduleJob.getBeanName(),
  33. scheduleJob.getMethodName(), scheduleJob.getParams());
  34. Future<?> future = service.submit(task);
  35. future.get();
  36. //任务执行总时长
  37. long times = System.currentTimeMillis() - startTime;
  38. logger.info("任务执行完毕,任务ID:" + scheduleJob.getId() + " 总共耗时:" + times + "毫秒");
  39. } catch (Exception e) {
  40. logger.error("任务执行失败,任务ID:" + scheduleJob.getId(), e);
  41. } finally {
  42. }
  43. }
  44. }

反射执行定时任务线程类:

  1. package com.mall.shop.util;
  2. import com.backstage.common.exception.BaseException;
  3. import org.apache.commons.lang3.StringUtils;
  4. import org.springframework.util.ReflectionUtils;
  5. import java.lang.reflect.Method;
  6. /**
  7. * 执行定时任务
  8. *
  9. */
  10. public class ScheduleRunnable implements Runnable {
  11. private Object target;
  12. private Method method;
  13. private String params;
  14. public ScheduleRunnable(String beanName, String methodName, String params) throws NoSuchMethodException, SecurityException {
  15. this.target = SpringContextUtils.getBean(beanName);
  16. this.params = params;
  17. if (StringUtils.isNotBlank(params)) {
  18. this.method = target.getClass().getDeclaredMethod(methodName, String.class);
  19. } else {
  20. this.method = target.getClass().getDeclaredMethod(methodName);
  21. }
  22. }
  23. @Override
  24. public void run() {
  25. try {
  26. ReflectionUtils.makeAccessible(method);
  27. if (StringUtils.isNotBlank(params)) {
  28. method.invoke(target, params);
  29. } else {
  30. method.invoke(target);
  31. }
  32. } catch (Exception e) {
  33. throw new BaseException(-1, "执行定时任务失败" + e.getMessage());
  34. }
  35. }
  36. }
Spring Context 工具类:
  1. package com.mall.shop.util;
  2. import org.springframework.beans.BeansException;
  3. import org.springframework.context.ApplicationContext;
  4. import org.springframework.context.ApplicationContextAware;
  5. import org.springframework.stereotype.Component;
  6. /**
  7. * Spring Context 工具类
  8. *
  9. */
  10. @Component
  11. public class SpringContextUtils implements ApplicationContextAware {
  12. public static ApplicationContext applicationContext;
  13. @Override
  14. public void setApplicationContext(ApplicationContext applicationContext)
  15. throws BeansException {
  16. SpringContextUtils.applicationContext = applicationContext;
  17. }
  18. public static Object getBean(String name) {
  19. return applicationContext.getBean(name);
  20. }
  21. public static <T> T getBean(String name, Class<T> requiredType) {
  22. return applicationContext.getBean(name, requiredType);
  23. }
  24. public static boolean containsBean(String name) {
  25. return applicationContext.containsBean(name);
  26. }
  27. public static boolean isSingleton(String name) {
  28. return applicationContext.isSingleton(name);
  29. }
  30. public static Class<? extends Object> getType(String name) {
  31. return applicationContext.getType(name);
  32. }
  33. /**
  34. * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
  35. */
  36. public static <T> T getBean(Class<T> requiredType) {
  37. return applicationContext.getBean(requiredType);
  38. }
  39. }

8.controller

  1. package com.mall.shop.controller;
  2. import com.backstage.system.log.LogOperation;
  3. import com.mall.shop.dto.request.ScheduleJobRequest;
  4. import com.mall.shop.entity.customized.ScheduleJobAO;
  5. import com.mall.shop.service.IScheduleJobService;
  6. import org.apache.shiro.authz.annotation.Logical;
  7. import org.apache.shiro.authz.annotation.RequiresPermissions;
  8. import org.slf4j.Logger;
  9. import org.slf4j.LoggerFactory;
  10. import org.springframework.web.bind.annotation.PostMapping;
  11. import org.springframework.web.bind.annotation.RequestBody;
  12. import org.springframework.web.bind.annotation.RestController;
  13. import javax.annotation.Resource;
  14. /**
  15. * Created by yangfeng on 2020/01/23.
  16. * 任务调度 controller
  17. */
  18. @RestController
  19. public class ScheduleJobController {
  20. private static Logger LOG = LoggerFactory.getLogger(ScheduleJobController.class);
  21. @Resource
  22. private IScheduleJobService scheduleJobService;
  23. /**
  24. * 分页查询任务调度
  25. *
  26. * @return
  27. */
  28. @PostMapping(value = "/scheduleJob/list")
  29. @RequiresPermissions(value = {"scheduleJob:view", "scheduleJob:manage"}, logical = Logical.OR)
  30. @LogOperation(action = "分页查询任务调度")
  31. public Object list(ScheduleJobRequest request) {
  32. return scheduleJobService.list(request);
  33. }
  34. /**
  35. * 新增任务调度
  36. *
  37. * @param scheduleJob
  38. * @return
  39. */
  40. @PostMapping(value = "/scheduleJob/add")
  41. @RequiresPermissions("scheduleJob:manage")
  42. @LogOperation(action = "新增任务调度")
  43. public Object add(ScheduleJobAO scheduleJob) {
  44. return scheduleJobService.add(scheduleJob);
  45. }
  46. /**
  47. * 修改任务调度
  48. *
  49. * @param scheduleJob
  50. * @return
  51. */
  52. @PostMapping(value = "/scheduleJob/update")
  53. @RequiresPermissions("scheduleJob:manage")
  54. @LogOperation(action = "修改任务调度")
  55. public Object update(ScheduleJobAO scheduleJob) {
  56. return scheduleJobService.update(scheduleJob);
  57. }
  58. /**
  59. * 删除任务调度
  60. *
  61. * @return
  62. */
  63. @PostMapping(value = "/scheduleJob/delete")
  64. @RequiresPermissions("scheduleJob:manage")
  65. @LogOperation(action = "删除任务调度")
  66. public Object delete(String[] jobIds) {
  67. return scheduleJobService.deleteBatch(jobIds);
  68. }
  69. @LogOperation(action = "立即执行任务")
  70. @PostMapping("/scheduleJob/run")
  71. @RequiresPermissions("scheduleJob:manage")
  72. public Object run(String[] jobIds) {
  73. return scheduleJobService.run(jobIds);
  74. }
  75. /**
  76. * 暂停定时任务
  77. *
  78. * @param jobIds jobIds
  79. */
  80. @LogOperation(action = "暂停定时任务")
  81. @PostMapping("/scheduleJob/pause")
  82. @RequiresPermissions("scheduleJob:manage")
  83. public Object pause(String[] jobIds) {
  84. return scheduleJobService.pause(jobIds);
  85. }
  86. /**
  87. * 恢复定时任务
  88. *
  89. * @param jobIds jobIds
  90. */
  91. @LogOperation(action = "恢复定时任务")
  92. @PostMapping("/scheduleJob/resume")
  93. @RequiresPermissions("scheduleJob:manage")
  94. public Object resume(String[] jobIds) {
  95. return scheduleJobService.resume(jobIds);
  96. }
  97. }

9.前端页面


10.任务执行类:

  1. package com.mall.shop.schedule;
  2. import com.mall.shop.entity.customized.PurchaseOrderAO;
  3. import com.mall.shop.enums.OrderStatus;
  4. import com.mall.shop.service.IPurchaseOrderService;
  5. import org.apache.commons.collections.CollectionUtils;
  6. import org.springframework.stereotype.Component;
  7. import javax.annotation.Resource;
  8. import java.util.List;
  9. /**
  10. * 过期自动取消订单
  11. */
  12. @Component
  13. public class OrderTask {
  14. @Resource
  15. private IPurchaseOrderService purchaseOrderService;
  16. public void expireOrder() {
  17. List<PurchaseOrderAO> orderList = purchaseOrderService.listExpireOrder().getData();
  18. if (!CollectionUtils.isEmpty(orderList)) {
  19. orderList.stream().forEach(o -> {
  20. o.setOrderStatus(OrderStatus.YQX.getCode());
  21. purchaseOrderService.update(o);
  22. });
  23. }
  24. }
  25. }

 

原文链接:https://blog.csdn.net/xiaoxiangzi520/article/details/117279128



所属网站分类: 技术文章 > 博客

作者:我爱编程

链接:http://www.javaheidong.com/blog/article/207724/bbfae7f7a288a0bbeedb/

来源:java黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

4 0
收藏该文
已收藏

评论内容:(最多支持255个字符)