首先引入jar包,版本统一由springboot-starter-parent管理

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

编写配置类

工厂类JobFactory

  1. /**
  2. * 定时任务工厂类配置
  3. *
  4. * @author lijun
  5. * @date 2021/11/23 11:12
  6. */
  7. @Component
  8. public class JobFactory extends AdaptableJobFactory implements ApplicationContextAware {
  9. @Autowired
  10. private transient AutowireCapableBeanFactory factory;
  11. @Override
  12. protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
  13. // 实例化对象
  14. Object job = super.createJobInstance(bundle);
  15. // 进行注入(Spring管理该Bean)
  16. factory.autowireBean(job);
  17. //返回对象
  18. return job;
  19. }
  20. @Override
  21. public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  22. factory = applicationContext.getAutowireCapableBeanFactory();
  23. }
  24. }

注入工厂对象及任务调度对象

  1. /**
  2. * 定时任务配置
  3. *
  4. * @author lijun
  5. * @date 2021/11/23 11:18
  6. */
  7. @Configuration
  8. public class QuartzConfig {
  9. @Autowired
  10. private JobFactory jobFactory;
  11. //创建调度器工厂
  12. @Bean(name = "SchedulerFactory")
  13. public SchedulerFactoryBean schedulerFactoryBean(){
  14. SchedulerFactoryBean factoryBean=new SchedulerFactoryBean();
  15. factoryBean.setJobFactory(jobFactory);
  16. return factoryBean;
  17. }
  18. @Bean(name = "scheduler")
  19. public Scheduler scheduler() {
  20. return schedulerFactoryBean().getScheduler();
  21. }
  22. }

封装定时任务管理类 负责增加、删除、启动、暂停等功能

  1. /**
  2. * 定时任务管理类 负责增加、删除、启动、暂停定时任务
  3. * @author lijun
  4. */
  5. @Component
  6. public class QuartzManager {
  7. private static final Logger logger = LoggerFactory.getLogger(QuartzManager.class);
  8. @Autowired
  9. private Scheduler scheduler;
  10. /**
  11. * 任务组
  12. */
  13. private static String JOB_GROUP_NAME = "任务组";
  14. /**
  15. * 触发器组
  16. */
  17. private static String TRIGGER_GROUP_NAME = "触发器组";
  18. /**
  19. * 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名
  20. *
  21. * @param jobName
  22. * 任务名
  23. * @param cls
  24. * 任务
  25. * @param time
  26. * 时间设置,参考quartz说明文档
  27. */
  28. public void addJob(String jobName, Class<? extends Job> cls, String time) {
  29. try {
  30. logger.info("构建作业实例......");
  31. // 用于描叙Job实现类及其他的一些静态信息,构建一个作业实例
  32. JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, JOB_GROUP_NAME).build();
  33. logger.info("创建触发器......");
  34. // 创建一个新的TriggerBuilder来规范一个触发器
  35. CronTrigger trigger = (CronTrigger) TriggerBuilder.newTrigger()
  36. // 给触发器起一个名字和组名
  37. .withIdentity(jobName, TRIGGER_GROUP_NAME)
  38. .withSchedule(CronScheduleBuilder.cronSchedule(time)).build();
  39. scheduler.scheduleJob(jobDetail, trigger);
  40. if (!scheduler.isShutdown()) {
  41. scheduler.start(); // 启动
  42. }
  43. } catch (Exception e) {
  44. shutdownJobs();
  45. throw new RuntimeException(e);
  46. }
  47. }
  48. /**
  49. * 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名 (带参数)
  50. *
  51. * @param jobName
  52. * 任务名
  53. * @param cls
  54. * 任务
  55. * @param time
  56. * 时间设置,参考quartz说明文档
  57. */
  58. public void addJob(String jobName, Class<? extends Job> cls, String time, Map<String, Object> parameter) {
  59. try {
  60. // 用于描叙Job实现类及其他的一些静态信息,构建一个作业实例
  61. JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, JOB_GROUP_NAME).build();
  62. // 传参数
  63. jobDetail.getJobDataMap().put("parameterMap", parameter);
  64. // 创建一个新的TriggerBuilder来规范一个触发器
  65. CronTrigger trigger = (CronTrigger) TriggerBuilder.newTrigger()
  66. // 给触发器起一个名字和组名
  67. .withIdentity(jobName, TRIGGER_GROUP_NAME)
  68. .withSchedule(CronScheduleBuilder.cronSchedule(time)).build();
  69. scheduler.scheduleJob(jobDetail, trigger);
  70. if (!scheduler.isShutdown()) {
  71. // 启动
  72. scheduler.start();
  73. }
  74. } catch (Exception e) {
  75. throw new RuntimeException(e);
  76. }
  77. }
  78. /**
  79. * 添加一个定时任务
  80. *
  81. * @param jobName
  82. * 任务名
  83. * @param jobGroupName
  84. * 任务组名
  85. * @param triggerName
  86. * 触发器名
  87. * @param triggerGroupName
  88. * 触发器组名
  89. * @param jobClass
  90. * 任务
  91. * @param time
  92. * 时间设置,参考quartz说明文档
  93. */
  94. public void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName,
  95. Class<? extends Job> jobClass, String time) {
  96. try {
  97. // 任务名,任务组,任务执行类
  98. JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();
  99. // 触发器
  100. CronTrigger trigger = (CronTrigger) TriggerBuilder
  101. .newTrigger().withIdentity(triggerName, triggerGroupName)
  102. .withSchedule(CronScheduleBuilder.cronSchedule(time)).build();
  103. scheduler.scheduleJob(jobDetail, trigger);
  104. if (!scheduler.isShutdown()) {
  105. // 启动
  106. scheduler.start();
  107. }
  108. } catch (Exception e) {
  109. throw new RuntimeException(e);
  110. }
  111. }
  112. /**
  113. * 添加一个定时任务 (带参数)
  114. *
  115. * @param jobName
  116. * 任务名
  117. * @param jobGroupName
  118. * 任务组名
  119. * @param triggerName
  120. * 触发器名
  121. * @param triggerGroupName
  122. * 触发器组名
  123. * @param jobClass
  124. * 任务
  125. * @param time
  126. * 时间设置,参考quartz说明文档
  127. */
  128. public void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName,
  129. Class<? extends Job> jobClass, String time, Map<String, Object> parameter) {
  130. try {
  131. JobDetail jobDetail = JobBuilder.newJob((Class<? extends Job>) jobClass).withIdentity(jobName, jobGroupName)
  132. // 任务名,任务组,任务执行类
  133. .build();
  134. // 传参数
  135. jobDetail.getJobDataMap().put("parameterMap", parameter);
  136. // 触发器
  137. CronTrigger trigger = (CronTrigger) TriggerBuilder
  138. .newTrigger().withIdentity(triggerName, triggerGroupName)
  139. .withSchedule(CronScheduleBuilder.cronSchedule(time)).build();
  140. scheduler.scheduleJob(jobDetail, trigger);
  141. if (!scheduler.isShutdown()) {
  142. scheduler.start(); // 启动
  143. }
  144. } catch (Exception e) {
  145. throw new RuntimeException(e);
  146. }
  147. }
  148. /**
  149. * 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名)
  150. *
  151. * @param jobName
  152. * 任务名
  153. * @param time
  154. * 新的时间设置
  155. */
  156. public void modifyJobTime(String jobName, String time) {
  157. try {
  158. // 通过触发器名和组名获取TriggerKey
  159. TriggerKey triggerKey = TriggerKey.triggerKey(jobName, TRIGGER_GROUP_NAME);
  160. // 通过TriggerKey获取CronTrigger
  161. CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
  162. if (trigger == null) {
  163. return;
  164. }
  165. String oldTime = trigger.getCronExpression();
  166. if (!oldTime.equalsIgnoreCase(time)) {
  167. // 通过任务名和组名获取JobKey
  168. JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME);
  169. JobDetail jobDetail = scheduler.getJobDetail(jobKey);
  170. Class<? extends Job> objJobClass = jobDetail.getJobClass();
  171. removeJob(jobName);
  172. addJob(jobName, objJobClass, time);
  173. }
  174. } catch (Exception e) {
  175. throw new RuntimeException(e);
  176. }
  177. }
  178. /**
  179. * 修改一个任务的触发时间
  180. *
  181. * @param triggerName
  182. * 任务名称
  183. * @param triggerGroupName
  184. * 传过来的任务名称
  185. * @param time
  186. * 更新后的时间规则
  187. */
  188. public void modifyJobTime(String triggerName, String triggerGroupName, String time) {
  189. try {
  190. // 通过触发器名和组名获取TriggerKey
  191. TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
  192. // 通过TriggerKey获取CronTrigger
  193. CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
  194. if (trigger == null) {
  195. return;
  196. }
  197. CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(trigger.getCronExpression());
  198. String oldTime = trigger.getCronExpression();
  199. if (!oldTime.equalsIgnoreCase(time)) {
  200. // 重新构建trigger
  201. trigger = (CronTrigger) trigger.getTriggerBuilder()
  202. .withIdentity(triggerKey).withSchedule(scheduleBuilder)
  203. .withSchedule(CronScheduleBuilder.cronSchedule(time)).build();
  204. // 按新的trigger重新设置job执行
  205. scheduler.rescheduleJob(triggerKey, trigger);
  206. }
  207. } catch (Exception e) {
  208. throw new RuntimeException(e);
  209. }
  210. }
  211. /**
  212. * 移除一个任务(使用默认的任务组名,触发器名,触发器组名)
  213. *
  214. * @param jobName
  215. * 任务名称
  216. */
  217. public void removeJob(String jobName) {
  218. try {
  219. // 通过触发器名和组名获取TriggerKey
  220. TriggerKey triggerKey = TriggerKey.triggerKey(jobName, TRIGGER_GROUP_NAME);
  221. // 通过任务名和组名获取JobKey
  222. JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME);
  223. // 停止触发器
  224. scheduler.pauseTrigger(triggerKey);
  225. // 移除触发器
  226. scheduler.unscheduleJob(triggerKey);
  227. // 删除任务
  228. scheduler.deleteJob(jobKey);
  229. } catch (Exception e) {
  230. throw new RuntimeException(e);
  231. }
  232. }
  233. /**
  234. * 移除一个任务
  235. *
  236. * @param jobName
  237. * 任务名
  238. * @param jobGroupName
  239. * 任务组名
  240. * @param triggerName
  241. * 触发器名
  242. * @param triggerGroupName
  243. * 触发器组名
  244. */
  245. public void removeJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName) {
  246. try {
  247. // 通过触发器名和组名获取TriggerKey
  248. TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
  249. // 通过任务名和组名获取JobKey
  250. JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
  251. // 停止触发器
  252. scheduler.pauseTrigger(triggerKey);
  253. // 移除触发器
  254. scheduler.unscheduleJob(triggerKey);
  255. // 删除任务
  256. scheduler.deleteJob(jobKey);
  257. } catch (Exception e) {
  258. throw new RuntimeException(e);
  259. }
  260. }
  261. /**
  262. * 启动所有定时任务
  263. */
  264. public void startJobs() {
  265. try {
  266. logger.info("启动定时器......");
  267. scheduler.start();
  268. } catch (Exception e) {
  269. throw new RuntimeException(e);
  270. }
  271. }
  272. /**
  273. * 关闭所有定时任务
  274. */
  275. public void shutdownJobs() {
  276. try {
  277. if (!scheduler.isShutdown()) {
  278. logger.info("关闭定时器......");
  279. scheduler.shutdown();
  280. }
  281. } catch (Exception e) {
  282. throw new RuntimeException(e);
  283. }
  284. }
  285. }

定时任务的增删停止,此处添加定时任务方法都是通过传入自己实现的Job类,然后反射创建对象,构造JobDetail(同一个Job构造的是不同的JobDetail),最后用schedule调度任务

定时任务类

  1. /**
  2. * 定时任务获取参数实例且执行任务
  3. *
  4. * @author lijun
  5. * @date 2021/8/17 14:29
  6. */
  7. @Component
  8. public class MyJob implements Job {
  9. @Resource
  10. private TaskJob taskJob;
  11. @Override
  12. public void execute(JobExecutionContext context) throws JobExecutionException {
  13. JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
  14. Map<String,Object> parameterMap = (Map<String,Object>)jobDataMap.get("parameterMap");
  15. String type = (String)parameterMap.get("type");
  16. if("task1".equals(type)){
  17. taskJob.task1();
  18. }else if("task2".equals(type)){
  19. taskJob.task2();
  20. }
  21. }
  22. }

TaskJob类

  1. /**
  2. * 公共 定时任务 类
  3. *
  4. * @author lijun
  5. * @date 2021/11/25 9:34
  6. */
  7. @Service
  8. public class TaskJob {
  9. @Resource
  10. CommonMapper commonMapper;
  11. public void task1(){
  12. //需要执行的业务
  13. List<Object> list = commonMapper.selectTask1();
  14. }
  15. public void task2(){
  16. //需要执行的业务
  17. List<Object> list = commonMapper.selectTask2();
  18. }
  19. }

手动设置时间并且启动任务

  1. Map<String,Object> params= new HashMap<>(4);
  2. params.put("type","task1");
  3. //两分钟执行一次
  4. quartzManager.addJob("task1", MyJob.class,"0 */2 * * * ?",params);

自动启动任务

  1. /**
  2. * 启动监听类
  3. *
  4. * @author lijun
  5. * @date 2021/11/25 9:56
  6. */
  7. @Slf4j
  8. @Component
  9. public class StartListener implements ApplicationListener<ApplicationStartedEvent> {
  10. @Resource
  11. private QuartzManager quartzManager;
  12. /**
  13. * 监听项目启动时运行定时任务
  14. *
  15. * @param event the event to respond to
  16. */
  17. @Override
  18. public void onApplicationEvent(ApplicationStartedEvent event) {
  19. log.info("定时程序启动:"+ DateUtil.dateToString(new Date(), SystemConstant.TIME_PATTEN));
  20. synDepartData();
  21. synPersonData();
  22. }
  23. public void synDepartData(){
  24. Map<String,Object> params= new HashMap<>(4);
  25. params.put("type","task1");
  26. quartzManager.addJob("task1", MyJob.class,"0 0 18 * * ?",params);
  27. // quartzManager.addJob("synDepartData", MyJob.class,"0 */2 * * * ?",params);
  28. }
  29. public void synPersonData(){
  30. Map<String,Object> params= new HashMap<>(4);
  31. params.put("type","task2");
  32. quartzManager.addJob("task2", MyJob.class,"0 0 18 * * ?",params);
  33. // quartzManager.addJob("synPersonData", MyJob.class,"0 */2 * * * ?",params);
  34. }
  35. }

参考地址:
springboot+Quartz开机启动定时任务,cron可配置