浅谈SpringBoot集成Quartz动态定时任务

SpringBoot自带schedule

沿用的springboot少xml配置的优良传统,本身支持表达式等多种定时任务
注意在程序启动的时候加上@EnableScheduling

@Scheduled(cron="0/5 * * * * ?")
 public void job(){
  System.out.println("每五秒执行一次");
 }

为什么要使用Quartz

多任务情况下,quartz更容易管理,可以实现动态配置
执行时间表达式:

表达式示例:

集成Quartz

如何搭建springboot就不再细说,官网和网上的教程很多。

maven依赖

<dependency>
   <groupId>org.quartz-scheduler</groupId>
   <artifactId>quartz</artifactId>
   <version>2.2.1</version>
  </dependency>

测试Job类
SchedulerQuartzJob1和SchedulerQuartzJob2代码差不多就不一一列出

package com.yvan.quartz.job;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
 * 实现Job接口
 * @author yvan
 *
 */
public class SchedulerQuartzJob1 implements Job{
 private void before(){
  System.out.println("任务开始执行");
 }

 @Override
 public void execute(JobExecutionContext arg0) throws JobExecutionException {
  before();
  System.out.println("开始:"+System.currentTimeMillis());
  // TODO 业务
  System.out.println("结束:"+System.currentTimeMillis());
  after();
 }

 private void after(){
  System.out.println("任务开始执行");
 }

}

任务调用处理
将其拆分成两个部分

实例化Job,将任务触发器加入任务调度中

 private void startJob1(Scheduler scheduler) throws SchedulerException {
  // 通过JobBuilder构建JobDetail实例,JobDetail规定只能是实现Job接口的实例
  // JobDetail 是具体Job实例
  JobDetail jobDetail = JobBuilder.newJob(SchedulerQuartzJob1.class).withIdentity("job1", "group1").build();
  // 基于表达式构建触发器
  CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
  // CronTrigger表达式触发器 继承于Trigger
  // TriggerBuilder 用于构建触发器实例
  CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("job1", "group1")
    .withSchedule(cronScheduleBuilder).build();
  scheduler.scheduleJob(jobDetail, cronTrigger);
 }

 private void startJob2(Scheduler scheduler) throws SchedulerException {
  JobDetail jobDetail = JobBuilder.newJob(SchedulerQuartzJob2.class).withIdentity("job2", "group2").build();
  CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0 0/5 * * * ?");
  CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("job2", "group2")
    .withSchedule(cronScheduleBuilder).build();
  scheduler.scheduleJob(jobDetail, cronTrigger);
 }

对外提供关于动态管理任务的方法

 /**
  * 开始执行所有任务
  *
  * @throws SchedulerException
  */
 public void startJob() throws SchedulerException {
  startJob1(scheduler);
  startJob2(scheduler);
  scheduler.start();
 }

 /**
  * 获取Job信息
  *
  * @param name
  * @param group
  * @return
  * @throws SchedulerException
  */
 public String getJobInfo(String name, String group) throws SchedulerException {
  TriggerKey triggerKey = new TriggerKey(name, group);
  CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
  return String.format("time:%s,state:%s", cronTrigger.getCronExpression(),
    scheduler.getTriggerState(triggerKey).name());
 }

 /**
  * 修改某个任务的执行时间
  *
  * @param name
  * @param group
  * @param time
  * @return
  * @throws SchedulerException
  */
 public boolean modifyJob(String name, String group, String time) throws SchedulerException {
  Date date = null;
  TriggerKey triggerKey = new TriggerKey(name, group);
  CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
  String oldTime = cronTrigger.getCronExpression();
  if (!oldTime.equalsIgnoreCase(time)) {
   CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(time);
   CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(name, group)
     .withSchedule(cronScheduleBuilder).build();
   date = scheduler.rescheduleJob(triggerKey, trigger);
  }
  return date != null;
 }

 /**
  * 暂停所有任务
  *
  * @throws SchedulerException
  */
 public void pauseAllJob() throws SchedulerException {
  scheduler.pauseAll();
 }

 /**
  * 暂停某个任务
  *
  * @param name
  * @param group
  * @throws SchedulerException
  */
 public void pauseJob(String name, String group) throws SchedulerException {
  JobKey jobKey = new JobKey(name, group);
  JobDetail jobDetail = scheduler.getJobDetail(jobKey);
  if (jobDetail == null)
   return;
  scheduler.pauseJob(jobKey);
 }

 /**
  * 恢复所有任务
  *
  * @throws SchedulerException
  */
 public void resumeAllJob() throws SchedulerException {
  scheduler.resumeAll();
 }

 /**
  * 恢复某个任务
  *
  * @param name
  * @param group
  * @throws SchedulerException
  */
 public void resumeJob(String name, String group) throws SchedulerException {
  JobKey jobKey = new JobKey(name, group);
  JobDetail jobDetail = scheduler.getJobDetail(jobKey);
  if (jobDetail == null)
   return;
  scheduler.resumeJob(jobKey);
 }

 /**
  * 删除某个任务
  *
  * @param name
  * @param group
  * @throws SchedulerException
  */
 public void deleteJob(String name, String group) throws SchedulerException {
  JobKey jobKey = new JobKey(name, group);
  JobDetail jobDetail = scheduler.getJobDetail(jobKey);
  if (jobDetail == null)
   return;
  scheduler.deleteJob(jobKey);
 }

完整代码

package com.yvan.quartz;

import java.util.Date;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import com.yvan.quartz.job.SchedulerQuartzJob1;
import com.yvan.quartz.job.SchedulerQuartzJob2;
/**
 * 任务调度处理
 * @author yvan
 *
 */
@Configuration
public class QuartzScheduler {
 // 任务调度
 @Autowired
 private Scheduler scheduler;

 /**
  * 开始执行所有任务
  *
  * @throws SchedulerException
  */
 public void startJob() throws SchedulerException {
  startJob1(scheduler);
  startJob2(scheduler);
  scheduler.start();
 }

 /**
  * 获取Job信息
  *
  * @param name
  * @param group
  * @return
  * @throws SchedulerException
  */
 public String getJobInfo(String name, String group) throws SchedulerException {
  TriggerKey triggerKey = new TriggerKey(name, group);
  CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
  return String.format("time:%s,state:%s", cronTrigger.getCronExpression(),
    scheduler.getTriggerState(triggerKey).name());
 }

 /**
  * 修改某个任务的执行时间
  *
  * @param name
  * @param group
  * @param time
  * @return
  * @throws SchedulerException
  */
 public boolean modifyJob(String name, String group, String time) throws SchedulerException {
  Date date = null;
  TriggerKey triggerKey = new TriggerKey(name, group);
  CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
  String oldTime = cronTrigger.getCronExpression();
  if (!oldTime.equalsIgnoreCase(time)) {
   CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(time);
   CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(name, group)
     .withSchedule(cronScheduleBuilder).build();
   date = scheduler.rescheduleJob(triggerKey, trigger);
  }
  return date != null;
 }

 /**
  * 暂停所有任务
  *
  * @throws SchedulerException
  */
 public void pauseAllJob() throws SchedulerException {
  scheduler.pauseAll();
 }

 /**
  * 暂停某个任务
  *
  * @param name
  * @param group
  * @throws SchedulerException
  */
 public void pauseJob(String name, String group) throws SchedulerException {
  JobKey jobKey = new JobKey(name, group);
  JobDetail jobDetail = scheduler.getJobDetail(jobKey);
  if (jobDetail == null)
   return;
  scheduler.pauseJob(jobKey);
 }

 /**
  * 恢复所有任务
  *
  * @throws SchedulerException
  */
 public void resumeAllJob() throws SchedulerException {
  scheduler.resumeAll();
 }

 /**
  * 恢复某个任务
  *
  * @param name
  * @param group
  * @throws SchedulerException
  */
 public void resumeJob(String name, String group) throws SchedulerException {
  JobKey jobKey = new JobKey(name, group);
  JobDetail jobDetail = scheduler.getJobDetail(jobKey);
  if (jobDetail == null)
   return;
  scheduler.resumeJob(jobKey);
 }

 /**
  * 删除某个任务
  *
  * @param name
  * @param group
  * @throws SchedulerException
  */
 public void deleteJob(String name, String group) throws SchedulerException {
  JobKey jobKey = new JobKey(name, group);
  JobDetail jobDetail = scheduler.getJobDetail(jobKey);
  if (jobDetail == null)
   return;
  scheduler.deleteJob(jobKey);
 }

 private void startJob1(Scheduler scheduler) throws SchedulerException {
  // 通过JobBuilder构建JobDetail实例,JobDetail规定只能是实现Job接口的实例
  // JobDetail 是具体Job实例
  JobDetail jobDetail = JobBuilder.newJob(SchedulerQuartzJob1.class).withIdentity("job1", "group1").build();
  // 基于表达式构建触发器
  CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
  // CronTrigger表达式触发器 继承于Trigger
  // TriggerBuilder 用于构建触发器实例
  CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("job1", "group1")
    .withSchedule(cronScheduleBuilder).build();
  scheduler.scheduleJob(jobDetail, cronTrigger);
 }

 private void startJob2(Scheduler scheduler) throws SchedulerException {
  JobDetail jobDetail = JobBuilder.newJob(SchedulerQuartzJob2.class).withIdentity("job2", "group2").build();
  CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0 0/5 * * * ?");
  CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("job2", "group2")
    .withSchedule(cronScheduleBuilder).build();
  scheduler.scheduleJob(jobDetail, cronTrigger);
 }
}

Scheduler 注入
这里采用监听spring容器加载完毕后事件,启动任务调用
将Scheduler交给spring初始化管理

package com.yvan.quartz;

import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;

@Configuration
public class ApplicationStartQuartzJobListener implements ApplicationListener<ContextRefreshedEvent>{
 @Autowired
 private QuartzScheduler quartzScheduler;

 /**
  * 初始启动quartz
  */
 @Override
 public void onApplicationEvent(ContextRefreshedEvent event) {
  try {
   quartzScheduler.startJob();
   System.out.println("任务已经启动...");
  } catch (SchedulerException e) {
   e.printStackTrace();
  }
 }

 /**
  * 初始注入scheduler
  * @return
  * @throws SchedulerException
  */
 @Bean
 public Scheduler scheduler() throws SchedulerException{
  SchedulerFactory schedulerFactoryBean = new StdSchedulerFactory();
  return schedulerFactoryBean.getScheduler();
 }

}

封装API
这里封装的API主要是为了方便动态管理执行任务,当然依赖这些接口也可以做一个界面来更直观的操作管理任务,这个就不再赘述。

package com.yvan.controller.quartzApi;

import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.yvan.quartz.QuartzScheduler;

/**
 * 这里并没有采用restful风格 只是简单封装了一下api
 *
 * @author yvan
 *
 */
@RestController
@RequestMapping("/quartz")
public class QuartzApiController {
 @Autowired
 private QuartzScheduler quartzScheduler;

 @RequestMapping("/start")
 public void startQuartzJob() {
  try {
   quartzScheduler.startJob();
  } catch (SchedulerException e) {
   e.printStackTrace();
  }
 }

 @RequestMapping("/info")
 public String getQuartzJob(String name, String group) {
  String info = null;
  try {
   info = quartzScheduler.getJobInfo(name, group);
  } catch (SchedulerException e) {
   e.printStackTrace();
  }
  return info;
 }

 @RequestMapping("/modify")
 public boolean modifyQuartzJob(String name, String group, String time) {
  boolean flag = true;
  try {
   flag = quartzScheduler.modifyJob(name, group, time);
  } catch (SchedulerException e) {
   e.printStackTrace();
  }
  return flag;
 }

 @RequestMapping(value = "/pause")
 public void pauseQuartzJob(String name, String group) {
  try {
   quartzScheduler.pauseJob(name, group);
  } catch (SchedulerException e) {
   e.printStackTrace();
  }
 }

 @RequestMapping(value = "/pauseAll")
 public void pauseAllQuartzJob() {
  try {
   quartzScheduler.pauseAllJob();
  } catch (SchedulerException e) {
   e.printStackTrace();
  }
 }

 @RequestMapping(value = "/delete")
 public void deleteJob(String name, String group) {
  try {
   quartzScheduler.deleteJob(name, group);
  } catch (SchedulerException e) {
   e.printStackTrace();
  }
 }

}

运行结果

任务已经启动...
18-03-02 14:39:46,879  INFO TomcatEmbeddedServletContainer:201 - Tomcat started on port(s): 8080 (http)
-03-02 14:39:46,883  INFO Start:57 - Started Start in 3.18 seconds (JVM running for 3.47)
任务开始执行
开始:1519972790003
结束:1519972790003
任务开始执行
任务开始执行
开始:1519972795000
结束:1519972795000
任务开始执行

以上所述是小编给大家介绍的SpringBoot集成Quartz动态定时任务详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • springboot整合Quartz实现动态配置定时任务的方法

    前言 在我们日常的开发中,很多时候,定时任务都不是写死的,而是写到数据库中,从而实现定时任务的动态配置,下面就通过一个简单的示例,来实现这个功能. 一.新建一个springboot工程,并添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency

  • springboot整合quartz实现定时任务示例

    在做项目时有时候会有定时器任务的功能,比如某某时间应该做什么,多少秒应该怎么样之类的. spring支持多种定时任务的实现.我们来介绍下使用spring的定时器和使用quartz定时器 1.我们使用spring-boot作为基础框架,其理念为零配置文件,所有的配置都是基于注解和暴露bean的方式. 2.使用spring的定时器: spring自带支持定时器的任务实现.其可通过简单配置来使用到简单的定时任务. @Component @Configurable @EnableScheduling p

  • springboot Quartz动态修改cron表达式的方法

    1.概述: 在开发中有的时候需要去手动禁止和启用定时任务,修改定时任务的cron表达式然后再让其动态生效,之前有过SSM的类似的业务的开发但是忘记写下来了...只好重新温习了一次,加上最近比较流行springBoot所以升级了一下用springBoot来完成. 2.关联技术 SpringBoot.Quartz.H2.thymeleaf (好像就这么多) 3.具体流程 1)首先去手动创建一个调度器工厂对象-SchedulerFactoryBean;其实应该不用手动创建的但是为了顾及到业务的复杂性所

  • springboot+Quartz实现任务调度的示例代码

    在spring框架中通过 @Schedule 可以实现定时任务,通过该注解 cron 的属性描述的规则,spring会去调用这个方法. spring已经简单粗暴的实现了定时任务,为什么要使用Quartz ? 如果你现在有很多个定时任务,规则不同,例如: 想每月25号,信用卡自动还款 想每年4月1日自己给当年暗恋女神发一封匿名贺卡 想每隔1小时,备份一下自己的爱情动作片 学习笔记到云盘 maven 依赖 <dependency> <groupId>org.quartz-schedul

  • SpringBoot与Quartz集成实现分布式定时任务集群的代码实例

    Spring Boot与Quartz集成实现分布式定时任务集群 直接贴代码 POM <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs

  • SpringBoot定时任务两种(Spring Schedule 与 Quartz 整合 )实现方法

    前言 最近在项目中使用到定时任务,之前一直都是使用Quartz 来实现,最近看Spring 基础发现其实Spring 提供 Spring Schedule 可以帮助我们实现简单的定时任务功能. 下面说一下两种方式在Spring Boot 项目中的使用. Spring Schedule 实现定时任务 Spring Schedule 实现定时任务有两种方式 1. 使用XML配置定时任务, 2. 使用 @Scheduled 注解. 因为是Spring Boot 项目 可能尽量避免使用XML配置的形式,

  • Springboot整个Quartz实现动态定时任务的示例代码

    简介 Quartz是一款功能强大的任务调度器,可以实现较为复杂的调度功能,如每月一号执行.每天凌晨执行.每周五执行等等,还支持分布式调度.本文使用Springboot+Mybatis+Quartz实现对定时任务的增.删.改.查.启用.停用等功能.并把定时任务持久化到数据库以及支持集群. Quartz的3个基本要素 Scheduler:调度器.所有的调度都是由它控制. Trigger: 触发器.决定什么时候来执行任务. JobDetail & Job: JobDetail定义的是任务数据,而真正的

  • 浅谈SpringBoot集成Quartz动态定时任务

    SpringBoot自带schedule 沿用的springboot少xml配置的优良传统,本身支持表达式等多种定时任务 注意在程序启动的时候加上@EnableScheduling @Scheduled(cron="0/5 * * * * ?") public void job(){ System.out.println("每五秒执行一次"); } 为什么要使用Quartz 多任务情况下,quartz更容易管理,可以实现动态配置 执行时间表达式: 表达式示例: 集成

  • SpringBoot集成Quartz实现定时任务的方法

    1 需求 在我的前后端分离的实验室管理项目中,有一个功能是学生状态统计.我的设计是按天统计每种状态的比例.为了便于计算,在每天0点,系统需要将学生的状态重置,并插入一条数据作为一天的开始状态.另外,考虑到学生的请假需求,请假的申请往往是提前做好,等系统时间走到实际请假时间的时候,系统要将学生的状态修改为请假. 显然,这两个子需求都可以通过定时任务实现.在网上略做搜索以后,我选择了比较流行的定时任务框架Quartz. 2 Quartz Quartz是一个定时任务框架,其他介绍网上也很详尽.这里要介

  • SpringBoot集成quartz实现定时任务详解

    目录 准备知识点 什么是Quartz Quartz的体系结构 什么是Quartz持久化 实现案例 - 单实例方式 实现案例 - 分布式方式 后端实现 前端实现 测试效果 准备知识点 需要了解常用的Quartz框架. 什么是Quartz 来源百度百科, 官网地址:http://www.quartz-scheduler.org/ Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用.Quartz可以用来

  • 浅谈SpringBoot集成Redis实现缓存处理(Spring AOP实现)

    第一章 需求分析 计划在Team的开源项目里加入Redis实现缓存处理,因为业务功能已经实现了一部分,通过写Redis工具类,然后引用,改动量较大,而且不可以实现解耦合,所以想到了Spring框架的AOP(面向切面编程). 开源项目:https://github.com/u014427391/jeeplatform 第二章 SpringBoot简介 Spring框架作为JavaEE框架领域的一款重要的开源框架,在企业应用开发中有着很重要的作用,同时Spring框架及其子框架很多,所以知识量很广.

  • springBoot项目集成quartz开发定时任务案例及注意事项

    目录 quartz下载.安装 实战案例 常见问题及解决方案 quartz下载.安装 Quartz是完全由java开发的一个开源的任务日程管理系统,任务进度管理器就是一个在预先确定的时间到达时,负责执行(或者通知)一段程序或功能的系统,即定时执行某个任务.Quartz用一个小Java库发布文件(.jar文件),这个库文件包含了所有Quartz核心功能.这些功能的主要接口(API)是Scheduler接口.它提供了简单的操作,例如:将任务纳入日程或者从日程中取消,开始/停止/暂停日程进度. 上图是q

  • 浅谈springboot项目中定时任务如何优雅退出

    在一个springboot项目中需要跑定时任务处理批数据时,突然有个Kill命令或者一个Ctrl+C的命令,此时我们需要当批数据处理完毕后才允许定时任务关闭,也就是当定时任务结束时才允许Kill命令生效. 启动类 启动类上我们获取到相应的上下文,捕捉相应命令.在这里插入代码片 @SpringBootApplication /**指定mapper对应包的路径*/ @MapperScan("com.youlanw.kz.dao") /**开启计划任务*/ @EnableScheduling

  • 浅谈springboot @Repository与@Mapper的区别

    目录 1.@Repository 2.@Mapper 3.区别 相同点: 不同点: 4.解决使用@mapper接口时,注入mapper爆红问题 今天在用springboot整合mybatis时,mapper接口上用的注解是以前学spring时用的@Repository注解,可一运行,就出现了错误. Error starting ApplicationContext. To display the conditions report re-run your application with 'de

  • 浅谈springboot中tk.mapper代码生成器的用法说明

    问:什么是tk.mapper? 答:这是一个通用的mapper框架,相当于把mybatis的常用数据库操作方法封装了一下,它实现了jpa的规范,简单的查询更新和插入操作都可以直接使用其自带的方法,无需写额外的代码. 而且它还有根据实体的不为空的字段插入和更新的方法,这个是非常好用的哈. 而且它的集成非常简单和方便,下面我来演示下使用它怎么自动生成代码. pom中引入依赖,这里引入tk.mybatis.mapper的版本依赖是因为在mapper-spring-boot-starter的新版本中没有

  • 浅谈springboot自动装配原理

    一.SpringBootApplication @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFi

  • 浅谈Linux C语言动态库及静态库

    假设在math目录下已编辑好add.c sub.c div.c mul.c func_point.c文件,func_point.c为包含main()的源文件! 动态库的制作: 方法一: gcc -c -fPIC add.c sub.c div.c mul.c //-c表示生成.o目标文件,-f后加一些编译选项,PIC表示与位置无关 gcc -shared -o libmymath.so add.o sub.o mul.o div.o//创建共享库mymath,添加add.o,sub.o,mul.

随机推荐