Spring 整合 Quartz框架(定时任务)
Maven 无法下载 Quartz 依赖,去官网下载 http://www.quartz-scheduler.org/downloads/
Quartz 官方手册:https://www.w3cschool.cn/quartz_doc/
需要注意
spring3.1以下的版本必须使用 quartz1.x 系列,3.1以上的版本才支持quartz2.x,不然会出错。
1、原因:spring 对 quartz 的支持实现,org.springframework.scheduling.quartz.CronTriggerBean 继承了 org.quartz.CronTrigger
在 quartz1.x 系列中 org.quartz.CronTrigger 是个类,而在quartz2.x系列中org.quartz.CronTrigger变成了接口,从而造成无法用spring的方式配置quartz的触发器。
1、做个小笔记,Quartz 对任务调度的领域问题进行了高度的抽象
1、提出了调度器、任务、触发器 这3个核心的概念
2、Job:是一个接口,只有一个方法 void execute(JobExecutionContext context),实现该接口定义运行任务,JobExecutionContext类提供了调度上下文的各种信息。
Job运行时的信息保存在JobDatMap 实例中
3、JobDetail:Quartz 在每次执行Job时,都重新创建一个Job实例,所以它不直接接受一个Job的实例,相反它接受一个Job实现类,以便运行时通过
nweInstance() 的反射机制实例化Job。因此需要通过一个类来描述Job的实现类及其他相关的静态信息,如Job名字、描述、关联监听器等信息,
JobDetail 承担了这一角色。
通过该类的构造函数可以更具体的了解它的作用:JobDetail( java.lang.String name , java.lang.String group , java.lang.Class jobClass)
该构造函数要去指定Job的实现类、以及任务在Scheduler 中的组名 和 Job 名称
4、Trigger:是一个类,描述触发了Job执行的时间触发规则。主要有 SimpleTrigger 和 CronTrigger 这两个子类
当仅需 触发 一次 或者 固定时间间隔周期执行,SimpleTrigger 是最合适的选择
CronTrigger 则可以通过 Cron 表达式定义出各种复杂时间规则的调度方案,如 每天早上9:00执行,周一、周三中午12:00执行等。
5、Calendar:org.quartz.Calendar 和 java.util.Calendar 不同,它是一些日历特定时间点的集合
(可以简单的将org.quartz.Calendar 看作 java.util.Calendar 的集合,java.util.Calendar 代表一个日历时间点)
一个 Trigger 可以和多个Calendar 关联,以便排除或包含某些时间点。
假设,我们安排每周星期一早上 10:00 执行任务,但是如果碰到法定的节日,任务则不执行,这时就需要Trigger触发机制
的基础上使用Calendar 进行定点排除,针对不同时间段类型,Quartz在org.quartz.impl.calendar包下提供了若干个Calendar的实现类,
如AnnualCalendar、MonthlyCalendar、WeeklyCalendar分别针对每年、每月和每周进行定义。
6、Scheduler:代表一个Quartz的独立运行容器,Trigger 和 JobDetail 可以注册到 Scheduler 中,两者在Schedule 中拥有各自
的组及名称,组及名称是Scheduler 查找定位容器中某一对象的依据,Trigger的组及名称必须唯一,JobDetail的组合名称也必须唯一(但可以和Trigger的组和名称相同,因为它们是不同类型的)
Scheduler 定义了多个接口方法,允许外部通过组及名称访问和控制容器中Trigger 和 JobDetail。
Scheduler 可以将Trigger绑定到 某一个 JobDetail 中,当Trigger触发时,对应的Job就被执行,一个Job可以对应多个Trigger,但一个Trigger只能对应一个Job。
可以通过SchedulerFactory 创建一个Scheduler实例。Scheduler拥有一个SchedulerContext,它类似于ServletContext,保存着Scheduler上下文信息,Job和Trigger都可以访问SchedulerContext内的信息。SchedulerContext内部通过一个Map,以键值对的方式维护这些上下文数据,SchedulerContext为保存和获取数据提供了多个put() 和 getXxx() 的方法。可以通过Scheduler.getContext() 获取对应的SchedulerContext实例。
7、ThreadPool:Scheduler 使用一个线程池作为任务运行的基础设施,任务通过共享线程池中的线程提高运行效率
8、Job有一个StatefulJob子接口,代表有状态的任务,改接口是一个没有方法的标签接口,其目的是让quartz知道任务的类型,以便采用不同的执行方案
嘿嘿,(*^▽^*) 直接抄大佬的总结,谢谢大佬的分享 https://blog.csdn.net/justdoit_potato/article/details/72841157
Spring 2.5 整合 quartz 1.7.3
我的环境:jdk7、quartz1.7.3 、spring-web 3.0.5 、spring 2.5
<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>1.7.3</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.4</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>3.0.5.RELEASE</version> </dependency>
由于某些原因.......,我就只贴工具类了...................................................................... 0.0
ScheduleJob.java
package com.zh.oukele.quartz3.entity; /** * CREATE BY OUKELE * CREATE TIME:2019/12/16 - 10:34 */ public class ScheduleJob { private String id; private String jobName; private String groupName; private String triggerName; private String triggerGroupName; private String jobStatus; private Boolean concurrent; private String cron; private String beanClass; private String methodName; private String jobData; public String getJobName() { return jobName; } public void setJobName(String jobName) { this.jobName = jobName; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getGroupName() { return groupName; } public void setGroupName(String groupName) { this.groupName = groupName; } public String getJobStatus() { return jobStatus; } public void setJobStatus(String jobStatus) { this.jobStatus = jobStatus; } public Boolean getConcurrent() { return concurrent; } public void setConcurrent(Boolean concurrent) { this.concurrent = concurrent; } public String getCron() { return cron; } public void setCron(String cron) { this.cron = cron; } public String getBeanClass() { return beanClass; } public void setBeanClass(String beanClass) { this.beanClass = beanClass; } public String getMethodName() { return methodName; } public void setMethodName(String methodName) { this.methodName = methodName; } public String getJobData() { return jobData; } public void setJobData(String jobData) { this.jobData = jobData; } public String getTriggerName() { return triggerName; } public void setTriggerName(String triggerName) { this.triggerName = triggerName; } public String getTriggerGroupName() { return triggerGroupName; } public void setTriggerGroupName(String triggerGroupName) { this.triggerGroupName = triggerGroupName; } @Override public String toString() { return "ScheduleJob{" + "id='" + id + '\'' + ", jobName='" + jobName + '\'' + ", groupName='" + groupName + '\'' + ", triggerName='" + triggerName + '\'' + ", triggerGroupName='" + triggerGroupName + '\'' + ", jobStatus='" + jobStatus + '\'' + ", concurrent=" + concurrent + ", cron='" + cron + '\'' + ", beanClass='" + beanClass + '\'' + ", methodName='" + methodName + '\'' + ", jobData='" + jobData + '\'' + '}'; } }
InitQuartzJob.java
package com.zh.oukele.quartz3; import com.zh.oukele.quartz3.entity.ScheduleJob; import com.zh.oukele.quartz3.util.QuartzJobFactory; import org.quartz.*; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import java.util.ArrayList; import java.util.List; /** * CREATE BY OUKELE * CREATE TIME:2019/12/16 - 9:59 */ public class InitQuartzJob implements ApplicationContextAware { private static ApplicationContext applicationContext; public static Scheduler scheduler = null; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { if( null == this.applicationContext ){ this.applicationContext = applicationContext; } } public void init(){ scheduler = (Scheduler) applicationContext.getBean("schedulerFactoryBean"); try { System.out.println( "schedule - init " + scheduler.getSchedulerName()); } catch (SchedulerException e) { e.printStackTrace(); } // 模拟数据库 ScheduleJob scheduleJob = new ScheduleJob(); scheduleJob.setId(""); scheduleJob.setJobName("myJob"); scheduleJob.setGroupName("myJobGroup1"); scheduleJob.setTriggerName("myTrigger"); scheduleJob.setTriggerGroupName("myTriggerGroup1"); scheduleJob.setCron("0/5 * * * * ?"); scheduleJob.setJobStatus("1"); scheduleJob.setConcurrent(true); // scheduleJob.setJobData("测试内容.....1"); scheduleJob.setMethodName("apple"); scheduleJob.setBeanClass("com.zh.oukele.quartz3.AppleTask"); try { addJob(scheduleJob); } catch (Exception e) { e.printStackTrace(); System.out.println("任务添加失败:" + e.getMessage()); } } // 添加任务 public void addJob(ScheduleJob scheduleJob) throws Exception { Trigger trigger = scheduler.getTrigger(scheduleJob.getTriggerName(), scheduleJob.getTriggerGroupName()); // 新任务 if( null == trigger ){ Class clazz = scheduleJob.getConcurrent()? QuartzJobFactory.class : null; // 描述任务清单 JobDetail jobDetail = new JobDetail(scheduleJob.getJobName(),scheduleJob.getGroupName(),clazz); jobDetail.getJobDataMap().put("scheduleJob", scheduleJob); // cron 触发器 CronTrigger cronTrigger = new CronTrigger(scheduleJob.getTriggerName(),scheduleJob.getTriggerGroupName(),scheduleJob.getJobName(),scheduleJob.getGroupName()); cronTrigger.setCronExpression(scheduleJob.getCron()); // 将任务 注册到 scheduler 中 scheduler.scheduleJob(jobDetail,cronTrigger); }else { // Trigger已存在,那么更新相应的定时设置 CronTrigger updateTrigger = (CronTrigger) trigger; updateTrigger.setCronExpression(scheduleJob.getCron()); scheduler.rescheduleJob(scheduleJob.getTriggerName(),scheduleJob.getTriggerGroupName(),updateTrigger); } } }
QuartzJobFactory.java
package com.zh.oukele.quartz3.util; import com.zh.oukele.quartz3.entity.ScheduleJob; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; /** * CREATE BY OUKELE * CREATE TIME:2019/12/16 - 11:17 * 计划任务执行处 无状态 */ public class QuartzJobFactory implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { ScheduleJob scheduleJob = (ScheduleJob) jobExecutionContext.getMergedJobDataMap().get("scheduleJob"); TaskUtil.invokMethod(scheduleJob); } }
TaskUtil.java
package com.zh.oukele.quartz3.util; import com.zh.oukele.quartz3.entity.ScheduleJob; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Date; /** * CREATE BY OUKELE * CREATE TIME:2019/12/16 - 11:43 */ public class TaskUtil implements BeanFactoryPostProcessor { private static ConfigurableListableBeanFactory beanFactory; // Spring应用上下文环境 @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { TaskUtil.beanFactory = configurableListableBeanFactory; } public static void invokMethod(ScheduleJob scheduleJob){ Object object = null; Class clazz = null; boolean flag = true; if (StringUtils.isNotBlank(scheduleJob.getId())) { object = beanFactory.getBean(scheduleJob.getId()); } if( object == null && StringUtils.isNotBlank(scheduleJob.getBeanClass()) ){ try { clazz = Class.forName(scheduleJob.getBeanClass()); object = clazz.newInstance(); } catch (Exception e) { flag = false; e.printStackTrace(); System.out.println("未找到"+scheduleJob.getBeanClass()+"对应的class," + new Date()); } } if( object == null ){ flag = false; System.out.println("任务名称 = [" + scheduleJob.getJobName()+ "]---------------未启动成功,请检查是否配置正确!!!"); return; } clazz = object.getClass(); Method method = null; try { if( StringUtils.isBlank(scheduleJob.getJobData()) ){ method = clazz.getDeclaredMethod(scheduleJob.getMethodName()); }else { method = clazz.getDeclaredMethod(scheduleJob.getMethodName(),new Class[]{String.class}); } } catch (NoSuchMethodException e) { e.printStackTrace(); flag = false; System.out.println("任务名称 = [" + scheduleJob.getJobName() + "] [class = "+ scheduleJob.getBeanClass() +"],未找到方法名为[ "+ scheduleJob.getMethodName() +" ] 的方法!!"); } if( method != null ){ try { if( StringUtils.isBlank(scheduleJob.getJobData()) ){ method.invoke(object); }else { method.invoke(object,scheduleJob.getJobData()); } } catch (IllegalAccessException e) { e.printStackTrace(); System.out.println("未找到"+scheduleJob.getBeanClass()+"类下"+scheduleJob.getMethodName()+"对应的方法参数设置错误"); } catch (InvocationTargetException e) { e.printStackTrace(); System.out.println("未找到"+scheduleJob.getBeanClass()+"类下"+scheduleJob.getMethodName()+"对应的方法参数设置错误"); } } if( flag ){ System.out.println("任务名称 = [" + scheduleJob.getJobName() + "]----------启动成功"); } } }
AppleTask.java
package com.zh.oukele.quartz3; import java.text.SimpleDateFormat; import java.util.Date; /** * CREATE BY OUKELE * CREATE TIME:2019/12/16 - 10:26 */ public class AppleTask { public void apple(){ System.out.println("-------------------------------" + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date())); } }
xml 配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd" default-lazy-init="false"> <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"/> <bean id="initQuartzJob" class="com.zh.oukele.quartz3.InitQuartzJob" init-method="init" lazy-init="false"/> </beans>
启动的效果....
每5秒执行一次( 然后 ..... 这个定时任务的停、删、改.... 有时间再放上来... )
Spring + quartz 2.x.x 版本的....................... 有时间 再贴出来...... 感觉好乱.........
Spring 整合 Quartz框架(定时任务)的更多相关文章
- spring整合quartz框架
spring整合quartz: 网上也有很多教程,好多都是基于配置方式,我们使用当然怎么简单就怎么用,所以这里介绍基于注解方式整合quartz.前提:你需要有一个能运行的web项目. 1.引依赖: & ...
- spring整合Quartz框架过程,大家可以参考下
这篇文章详细介绍了spring集成quartz框架流程,通过示例代码进行了详细说明,对学习或任务有参考学习价值,并可供需要的朋友参考. 1.quartz框架简介(m.0831jl.com) quart ...
- 【淘淘】Spring整合Quartz框架
我在外面工作实习的时候,我们做的项目是一个日报子系统,也就是定时定点为公司生成一些报表数据还有一些数据反馈.这时候我们会经常用到定时任务,比如每天凌晨生成前天报表,每一小时生成汇总数据等等.当时,我做 ...
- Spring整合quartz框架实现任务定时调度
1. 首先需要引入需要的jar包,如上图所示. 2. 编写需要定时调度的测试类: package com.jp.task; import java.util.Date; public class T ...
- spring整合quartz实现定时任务
需求:spring+mybatis框架已经搭建好,需要实现一个定时任务. 一:导出相应的jar包 quartz-all-1.6.5.jar获取quartz-alll-1.6.6.jar spring- ...
- Spring整合Quartz分布式定时任务
概述虽然单个Quartz实例能给予你很好的Job调度能力,但它不能满足典型的企业需求,如可伸缩性.高可靠性满足.假如你需要故障转移的能力并能运行日益增多的 Job,Quartz集群势必成为你应用的一部 ...
- spring整合quartz时间任务调度框架
spring整合quartz框架 1.创建maven工程 2.导入jar包(pom.xml) <dependencies> <dependency> <groupId&g ...
- 使用Spring整合Quartz轻松完成定时任务
一.背景 上次我们介绍了如何使用Spring Task进行完成定时任务的编写,这次我们使用Spring整合Quartz的方式来再一次实现定时任务的开发,以下奉上开发步骤及注意事项等. 二.开发环境及必 ...
- Spring整合Quartz定时任务 在集群、分布式系统中的应用(Mysql数据库环境)
Spring整合Quartz定时任务 在集群.分布式系统中的应用(Mysql数据库环境) 转载:http://www.cnblogs.com/jiafuwei/p/6145280.html 单个Q ...
随机推荐
- [转帖]重估BAT与华为的云上野心
重估BAT与华为的云上野心 https://www.leiphone.com/news/201910/Z5aLhckqUjCNJ49o.html 本文作者:王刚 2019-10-11 16:19 导语 ...
- Nginx 系列教程
Nginx(一):Nginx介绍 Nginx(二):编译安装Nginx及参数说明 Nginx(三):nginx.conf配置文件说明 [1] 配置参数说明 Nginx(三):nginx.conf配置文 ...
- python gdal安装与简单使用
原文链接:python gdal安装与简单使用 gdal安装方式一:在网址 https://www.lfd.uci.edu/~gohlke/pythonlibs/#gdal 下载对应python版本的 ...
- C++开发新版本vs使用旧版本vs编译的静态库动态库
关于vs潜在的升级问题概述 (Visual C++)查看官网的介绍:潜在的升级问题概述 (Visual C++).主要问题: 1. 如果使用 /GL(全程序优化)进行编译,则生成的对象文件只能使用生成 ...
- golang 管理 pidfile
Pidfile 存储了进程的进程 id.一般情况下 pidfile 有以下几个作用: 其他进程可以读取 pidfile 获取运行进程的 pid(当然也可以通过其他命令 动态获取) 在启动进程前先检查 ...
- PHP Math函数
abs() 绝对值. acos() 反余弦. acosh() 反双曲余弦. asin() 反正弦. asinh() 反双曲正弦. atan() 反正切. atan2() 两个参 ...
- string类型的解释与方法
基本概念 string(严格来说应该是System.String) 类型是我们日常coding中用的最多的类型之一.那什么是String呢?^ ~ ^ String是一个不可变的连续16位的Unico ...
- vue+iview 通过a标签实现文件下载
vue+iview 通过a标签实现文件下载 方法一: 注意: 如果下载的文件放在本地目录下,一定要将模板文件放到 public 目录下,否则由于权限问题找不到文件 路径: 项目更目录-->pub ...
- rhel7下安装EPEL源
1.rhel7安装aliyun下的epel源 wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
- Linux命令——procinfo
简介 proc文件系统是一个虚拟文件系统,包含有关进程和系统信息的文件. proc 文件系统开机时自动挂载并映射到/proc目录.许多程序从/proc目录中检索信息,对其进行处理并使其易于用于各种目的 ...