Quartz入门教程
Quartz学习--quartz基本介绍和Cron表达式
Quartz学习--quartz基本介绍和Cron表达式表名称说明qrtz_blob_triggers Trigger作为Blob类型存储(⽤于Quartz⽤户⽤JDBC创建他们⾃⼰定制的Trigger类型,JobStore 并不知道如何存储实例的时候)qrtz_calendars以Blob类型存储Quartz的Calendar⽇历信息, quartz可配置⼀个⽇历来指定⼀个时间范围负责执⾏向QuartzScheduler注册的触发Trigger的⼯作线程ThreadPool :Scheduler使⽤⼀个线程作为任务运⾏的基础设施,任务通过共享线程池中的线程提⾼运⾏效率QuartzSchedulerResources :包含穿件QuartzScheduler实例所需的所有资源(JobStore,ThreadPool等)JobStore :通过类实现的接⼝,这些类要为org.quartz.core.QuartzScheduler的使⽤提供⼀个org.quartz.Job和org.quartz.Trigger存储机制.作业和触发器的存储应该以其名称和组的组合为唯⼀性QuartzScheduler :Quartz的核⼼,他是org.quartz.Scheduler接⼝的间接实现,包含调度org.quartz.Jobs ,注册org.quartz.JobListener实例等的⽅法Scheduler :这是Quartz Scheduler的主要接⼝,代表⼀个独⽴运⾏容器. 调度程序维护JobDetails和触发器的注册表.⼀旦注册,调度程序负责执⾏作业,当她们的相关连的触发器触发(当她们的预定时间到达时 )Trigger:具有所有触发器通⽤属性的基本接⼝,描述了job执⾏的时间触发规则,使⽤TriggerBuilder实例化实际触发器JobDetail :传递给定作业实例的详细信息属性.JobDetails将使⽤JobBuilder创建/定义Job :表⽰要执⾏的"作业"的类的实现接⼝.只有⼀个⽅法:void execute(JobExecutionContext context);(JobExecutionContext 提供调度上下⽂各种信息,运⾏时数据保存在jobDataMap中 )Job 有个⼦接⼝StatefulJob,代表没有状态任务有状态任务不可并发,前次任务没有执⾏完,后⾯任务则⼀直处于阻塞等待状态2. ⼀个job可以被多个Trigger 绑定,但是⼀个Trigger只能绑定⼀个job!7. quartz.properties Quartz可更改配置//调度标识名集群中每⼀个实例都必须使⽤相同的名称(区分特定的调度器实例)org.quartz.scheduler.instanceName:DefaultQuartzScheduler//ID设置为⾃动获取每⼀个必须不同(所有调度器实例中是唯⼀的)org.quartz.scheduler.instanceId :AUTO//数据保存⽅式为持久化org.quartz.jobStore.class :org.quartz.impl.jdbcjobstore.JobStoreTX//表的前缀org.quartz.jobStore.tablePrefix : QRTZ_//设置为TRUE不会出现序列化⾮字符串类到 BLOB 时产⽣的类版本问题//eProperties : true//加⼊集群 true 为集群 false不是集群org.quartz.jobStore.isClustered : false//调度实例失效的检查时间间隔org.quartz.jobStore.clusterCheckinInterval:20000//容许的最⼤作业延长时间org.quartz.jobStore.misfireThreshold :60000//ThreadPool 实现的类名org.quartz.threadPool.class:org.quartz.simpl.SimpleThreadPool//线程数量org.quartz.threadPool.threadCount : 10//线程优先级org.quartz.threadPool.threadPriority : 5(threadPriority 属性的最⼤值是常量 ng.Thread.MAX_PRIORITY,等于10。
Quartz开发指南
定时器(Quartz)使用说明本文目前主要包括如下几个部分:Quartz功能简介:介绍Quartz的特点及概念。
使用Quartz的常见问题:很多用户在使用过程中遇到常见问题的解答。
快速开始:让读者尽快掌握Quartz开发。
Quartz官方开发指南:通过一些列的课程来指导如何使用Quartz.Quartz功能简介Quartz特点:z Quartz能嵌入到任何独立的应用中运行。
z Quartz能在应用服务器或者Servlet容器中实例化,并且能够参与XA事务。
z Quartz能够以独立的方式运行(在它自己的Java虚拟机中),可以通过RMI使用Quartz。
z Quartz可以被实例化为独立程序的集群(有负载均衡和容错能力)。
Job Scheduling(任务日程安排)任务在给定的触发器(Trigger)触发时执行。
触发器可以通过几乎以下所有形式的组合方式进行创建:z在一天中的任意时刻(可以精确到毫秒)。
z一周中特定的一些天。
z一个月中特定的一些天。
z一年中特定的一些天z不在日历列表中注册的一些天(比如节假日)。
z循环特定的次数。
z循环到特定的时间。
z无限循环。
z按照一定的时间间隔循环。
“任务”由创建者给定名字,并且可以加入到给定名称的“任务组”中。
为了简化触发器在日程中的管理,“触发器”也可以被给定名字和分组。
任务只能加入到日程中一次,但是可以为其注册多个触发器。
在J2EE环境中,任务可以作为分布(XA)事务的一部分执行。
Job Execution(任务执行)•任务是任何实现简单Job接口的Java 类,这样开发者能够执行任何完成他们工作的任务。
•任务类的实例可以由Quartz实例化,也可以由你的程序框架实例化。
当触发器被触发时,日程管理器将会通知某个或者多个实现了JobListener 或TriggerListener的对象(监听器可以是简单的Java对象,或者EJBs,或者JMS消息发布器,等等)。
详细讲解Quartz如何从入门到精通
详细讲解Quartz如何从入门到精通Quartz是一个开源的作业调度框架它完全由Java写成并设计用于J SE和J EE应用中它提供了巨大的灵活性而不牺牲简单性你能够用它来为执行一个作业而创建简单的或复杂的调度它有很多特征如数据库支持集群插件EJB作业预构建JavaMail及其它支持cron like 表达式等等你曾经需要应用执行一个任务吗?这个任务每天或每周星期二晚上或许仅仅每个月的最后一天执行一个自动执行而无须干预的任务在执行过程中如果发生一个严重错误应用能够知到其执行失败并尝试重新执行吗?你和你的团队是用Java编程吗?如果这些问题中任何一个你回答是那么你应该使用Quartz调度器旁注 Matrix目前就大量使用到了Quartz 比如排名统计功能的实现在Jmatrix里通过Quartz定义了一个定时调度作业在每天凌晨一点作业开始工作重新统计大家的Karma和排名等还有 RSS文件的生成也是通过Quartz定义作业每隔半个小时生成一次RSS XML文件Quartz让作业调度简单Quartz是一个完全由Java编写的开源作业调度框架不要让作业调度这个术语吓着你尽管Quartz框架整合了许多额外功能但就其简易形式看你会发现它易用得简直让人受不了!简单地创建一个实现quartz Job接口的Java类 Job接口包含唯一的方法在你的Job接口实现类里面添加一些逻辑到execute()方法一旦你配置好Job实现类并设定好调度时间表 Quartz将密切注意剩余时间当调度程序确定该是通知你的作业的时候 Quartz框架将调用你Job实现类(作业类)上的execute()方法并允许做它该做的事情无需报告任何东西给调度器或调用任何特定的东西仅仅执行任务和结束任务即可如果配置你的作业在随后再次被调用 Quartz框架将在恰当的时间再次调用它如果你使用了其它流行的开源框架象struts 你会对Quartz的设计和部件感到舒适虽然两个开源工程是解决完全不同的问题还是有很多相似的之处就是开源软件用户每天感觉很舒适Quartz能用在单机J SE应用中作为一个RMI服务器也可以用在web应用中甚至也可以用在J EE应用服务器中Quartz的发展史尽管Quartz今年开始受到人们注意但还是暂时流行Quartz由James House创建并最初于年春天被加入sourcefe工程接下来的几年里有许多新特征和版本出现但是直到项目迁移到新的站点并成为OpenSymphony项目家族的一员才开始真正启动并受到应有的关注James House仍然和几个协助他的业余开发者参与大量开发工作Quartz开发团队今年能发布几个新版本包括当前正处在候选发布阶段的版上手QuartzQuartz工程驻留在OpenSymphony站点上在Quartz站点上可以找到许多有用的资源 JavaDocs 包含指南的文档 CVS访问用户和开发者论坛的连接当然也有下载从下载连接取得Quartz的发布版本并且解压到到本地目录这个下载文件包含了一个预先构建好的Quartz二进制文件(quartz jar)你可以将它放进自己的应用中Quartz框架只需要少数的第三方库并且这些三方库是必需的你很可能已经在使用这些库了你要把Quartz的安装目录的/lib/core 和 /lib/optional目录中的第三方库加进你自己的工程中大多数第三方库是我们所熟知和喜欢的标准Jakarta Commons库像Commons Logging Commons BeantUtils等等quartz properties文件Quartz有一个叫做quartz properties的配置文件它允许你修改框架运行时环境缺省是使用Quartz jar里面的quartz properties文件当然你应该创建一个quartz properties文件的副本并且把它放入你工程的classes目录中以便类装载器找到它一旦将Quartz jar文件和第三方库加到自己的工程里面并且quartz properties文件在工程的classes目录中就可以创建作业了然而在做这之前我们暂且回避一下先简短讨论一下Quartz架构Quartz内部架构在规模方面 Quartz跟大多数开源框架类似大约有个Java类和接口并被组织到个包中这可以和Apache Struts把大约个类和接口以及组织到个包中相比尽管规模几乎不会用来作为衡量框架质量的一个特性但这里的关键是quarts内含很多功能这些功能和特性集是否成为或者应该成为评判一个开源或非开源框架质量的因素Quartz调度器Quartz框架的核心是调度器调度器负责管理Quartz应用运行时环境调度器不是靠自己做所有的工作而是依赖框架内一些非常重要的部件 Quartz不仅仅是线程和线程管理为确保可伸缩性 Quartz采用了基于多线程的架构启动时框架初始化一套worker线程这套线程被调度器用来执行预定的作业这就是Quartz怎样能并发运行多个作业的原理 Quartz依赖一套松耦合的线程池管理部件来管理线程环境本文中我们会多次提到线程池管理但Quartz里面的每个对象是可配置的或者是可定制的所以例如如果你想要 *** 自己线程池管理设施我猜你一定能!作业用Quartz的行话讲作业是一个执行任务的简单Java类任务可以是任何Java代码只需你实现 quartz Job接口并且在出现严重错误情况下抛出JobExecutionException异常即可Job接口包含唯一的一个方法execute() 作业从这里开始执行一旦实现了Job接口和execute()方法当Quartz确定该是作业运行的时候它将调用你的作业Execute()方法内就完全是你要做的事情下面有一些你要在作业里面做事情的例子· 用JavaMail(或者用其他的像Commons Net一样的邮件框架)发送邮件· 创建远程接口并且调用在EJB上的方法· 获取Hibernate Session 查询和更新关系数据库里的数据· 使用OSWorkflow并且从作业调用一个工作流· 使用FTP和到处移动文件· 调用Ant构建脚本开始预定构建这种可能性是无穷的正事这种无限可能性使得框架功能如此强大Quartz给你提供了一个机制来建立具有不同粒度的可重复的调度表于是你只需创建一个Java类这个类被调用而执行任务作业管理和存储作业一旦被调度调度器需要记住并且跟踪作业和它们的执行次数如果你的作业是分钟后或每秒调用这不是很有用事实上作业执行需要非常准确和即时调用在被调度作业上的execute()方法Quartz通过一个称之为作业存储(JobStore)的概念来做作业存储和管理有效作业存储Quartz提供两种基本作业存储类型第一种类型叫做RAMJobStore 它利用通常的内存来持久化调度程序信息这种作业存储类型最容易配置构造和运行对许多应用来说这种作业存储已经足够了然而因为调度程序信息是存储在被分配给JVM的内存里面所以当应用程序停止运行时所有调度信息将被丢失如果你需要在重新启动之间持久化调度信息则将需要第二种类型的作业存储第二种类型的作业存储实际上提供两种不同的实现但两种实现一般都称为JDBC作业存储两种JDBC作业存储都需要JDBC驱动程序和后台数据库来持久化调度程序信息这两种类型的不同在于你是否想要控制数据库事务或这释放控制给应用服务器例如BEA s WebLogic 或Jboss (这类似于J EE领域中Bean管理的事务和和容器管理事务之间的区别)这两种JDBC作业存储是· JobStoreTX 当你想要控制事务或工作在非应用服务器环境中是使用· JobStoreCMT 当你工作在应用服务器环境中和想要容器控制事务时使用JDBC作业存储为需要调度程序维护调度信息的用户而设计作业和触发器Quartz设计者做了一个设计选择来从调度分离开作业Quartz中的触发器用来告诉调度程序作业什么时候触发框架提供了一把触发器类型但两个最常用的是SimpleTrigger和CronTrigger SimpleTrigger 为需要简单打火调度而设计典型地如果你需要在给定的时间和重复次数或者两次打火之间等待的秒数打火一个作业那么SimpleTrigger适合你另一方面如果你有许多复杂的作业调度那么或许需要CronTriggerCronTrigger是基于Calendar like调度的当你需要在除星期六和星期天外的每天上午点半执行作业时那么应该使用CronTrigger 正如它的名字所暗示的那样 CronTrigger是基于Unix克隆表达式的作为一个例子下面的Quartz克隆表达式将在星期一到星期五的每天上午点分执行一个作业* MON FRI下面的表达式* L将在年到年的每个月的最后一个星期五上午点分执行作业你不可能用SimpleTrigger来做这些事情你可以用两者之中的任何一个但哪个跟合适则取决于你的调度需要调度一个作业让我们通过看一个例子来进入实际讨论现假定你管理一个部门无论何时候客户在它的FTP服务器上存储一个文件都得用电子邮件通知它我们的作业将用FTP登陆到远程服务器并下载所有找到的文件然后它将发送一封含有找到和下载的文件数量的电子邮件这个作业很容易就帮助人们整天从手工执行这个任务中解脱出来甚至连晚上都无须考虑我们可以设置作业循环不断地每秒检查一次而且工作在× 模式下这就是Quartz框架完全的用途首先创建一个Job类将执行FTP和Email逻辑下例展示了Quartz 的Job类它实现了 quartz Job接口我们故意让ScanFTPSiteJob保持很简单我们为这个例子创建了一个叫做JobUtil的实用类它不是Quartz的组成部分但对构建各种作业能重用的实用程序库来说是有意义的我们可以轻易将那种代码组织进作业类中 quarts 调度器一样好用因为我们一直在使用quarts 所以那些代码可继续重用JobUtil checkForFiles() and JobUtil sendEmail()方法使用的参数是Quartz创建的JobDataMap的实例实例为每个作业的执行而创建它是向作业类传递配置参数的方法这里并没有展示JobUtil的实现但我们能用Jakarta上的Commons Net轻易地实现FTP和Email功能用调度器调用作业首先创建一个作业但为使作业能被调度器调用你得向调度程序说明你的作业的调用时间和频率这个事情由与作业相关的触发器来完成因为我们仅仅对大约每秒循环调用作业感兴趣所以打算使用SimpleTrigger作业和触发器通过Quartz调度器接口而被调度我们需要从调度器工厂类取得一个调度器的实例最容易的办法是调用StdSchedulerFactory这个类上的静态方法getDefaultScheduler() 使用Quartz框架你需要调用start()方法来启动调度器例的代码遵循了大多数Quartz应用的一般模式创建一个或多个作业创建和设置触发器用调度器调度作业和触发器启动调度器编程调度同声明性调度我们通过编程的方法调度我们的ScanFTPSiteJob作业就是说我们用Java代码来设置作业和触发器Quartz框架也支持在xml文件里面申明性的设置作业调度申明性方法允许我们更快速地修改哪个作业什么时候被执行Quartz框架有一个插件这个插件负责读取xml配置文件xml配置文件包含了关于启动Quartz应用的作业和触发器信息所有xml文件中的作业连同相关的触发器都被加进调度器你仍然需要编写作业类但配置那些作业类的调度器则非常动态化你可以将xml文件中的元素跟例代码作个比较它们从概念上来看是相同的使用申明性方法的好处是维护变得极其简单只需改变xml配置文件和重新启动Quartz应用即可无须修改代码无须重新编译无须重新部署有状态和无状态作业在本文中你所看到的作业到是无状态的这意味着在两次作业执行之间不会去维护作业执行时JobDataMap的状态改变如果你需要能增删改JobDataMap的值而且能让作业在下次执行时能看到这个状态改变则需要用Quartz有状态作业如果你是一个有经验的EJB开发者的话深信你会立即退缩因为有状态带有负面含义这主要是由于EJB带来的伸缩性问题Quartz有状态作业实现了 quartz StatefulJob接口无状态和有状态作业的关键不同是有状态作业在每次执行时只有一个实例大多数情况下有状态的作业不回带来大的问题然而如果你有一个需要频繁执行的作业或者需要很长时间才能完成的作业那么有状态作业可能给你带来伸缩性问题Quartz框架的其他特征Quartz框架有一个丰富的特征集事实上quarts有太多特性以致不能在一种情况中全部领会下面列出了一些有意思的特征但没时间在此详细讨论监听器和插件每个人都喜欢监听和插件今天几乎下载任何开源框架你必定会发现支持这两个概念监听是你创建的Java类当关键事件发生时会收到框架的回调例如当一个作业被调度没有调度或触发器终止和不再打火时这些都可以通过设置来来通知你的监听器Quartz框架包含了调度器监听作业和触发器监听你可以配置作业和触发器监听为全局监听或者是特定于作业和触发器的监听一旦你的一个具体监听被调用你就能使用这个技术来做一些你想要在监听类里面做的事情例如你如果想要在每次作业完成时发送一个电子邮件你可以将这个逻辑写进作业里面也可以JobListener里面写进JobListener的方式强制使用松耦合有利于设计上做到更好Quartz插件是一个新的功能特性无须修改Quartz源码便可被创建和添加进Quartz框架他为想要扩展Quartz框架又没有时间提交改变给Quartz开发团队和等待新版本的开发人员而设计如果你熟悉Struts插件的话那么完全可以理解Quartz插件的使用与其Quartz提供一个不能满足你需要的有限扩展点还不如通过使用插件来拥有可修整的扩展点集群Quartz应用Quartz应用能被集群是水平集群还是垂直集群取决于你自己的需要集群提供以下好处· 伸缩性· 搞可用性· 负载均衡目前Quartz只能借助关系数据库和JDBC作业存储支持集群将来的版本这个制约将消失并且用RAMJobStore集群将是可能的而且将不需要数据库的支持Quartz web应用使用框架几个星期或几个月后 Quartz用户所显示的需求之一是需要集成Quartz到图形用户界面中目前Quartz框架已经有一些工具允许你使用Java servlet来初始化和启动Quartz 一旦你可以访问调度器实例你就可以把它存储在web容器的servlet上下文中(ServletContext中)并且可以通过调度器接口管理调度环境幸运的是一些开发者已正影响着单机Quartz web应用它用来更好地管理调度器环境构建在若干个流行开源框架如Struts和Spring 之上的图形用户界面支持很多功能这些功能都被包装进一个简单接口Quartz的下一步计划Quartz是一个活动中的工程Quartz开发团队明确表示不会停留在已有的荣誉上Quartz下一个主要版本已经在启动中你可以在OpenSymphony的wiki上体验一下Quartz 的设计和特征总之Quartz用户每天都自由地添加特性建议和设计创意以便能被核心框架考虑(看重)了解更多Quartz特征lishixinzhi/Article/program/Java/ky/201311/27892。
quartz用法
Quartz用法一、什么是Quartz?Quartz是一个功能强大且广泛应用于Java中的开源任务调度框架。
它允许开发人员通过简单而灵活的方式在应用程序中调度和执行任务。
无论是简单的定时任务还是复杂的作业调度,Quartz都可以满足需求。
二、Quartz的基本概念在深入探讨Quartz的用法之前,我们首先需要了解一些基本概念。
1. 作业(Job)作业是Quartz中最基本的调度单元。
它表示一项任务或一个操作,可以被Quartz 调度和执行。
2. 触发器(Trigger)触发器是Quartz中用于指定作业何时执行的组件。
可以根据时间表达式(如每小时、每天等)来触发作业的执行,也可以根据特定的日期和时间来触发。
3. 调度器(Scheduler)调度器是Quartz的核心组件,它负责在指定的时间触发作业的执行。
调度器可以同时管理多个作业和触发器,并根据设定的调度策略来决定执行顺序。
三、Quartz的用法接下来,我们将深入探讨Quartz的用法,包括作业和触发器的创建、调度器的配置和管理。
1. 创建作业要创建一个作业,我们需要定义一个类,实现Quartz的Job接口,并重写其中的execute()方法。
在execute()方法中,我们可以编写具体的任务逻辑。
例如:public class MyJob implements Job {public void execute(JobExecutionContext context) throws JobExecutionExcept ion {// 编写具体的任务逻辑}}2. 创建触发器Quartz提供了多种触发器类型,可以根据需求灵活选择。
其中最常用的是SimpleTrigger和CronTrigger。
•SimpleTrigger:简单触发器会在指定的时间间隔内循环执行作业。
可以设置作业的开始时间、结束时间和重复次数。
•CronTrigger:基于Cron表达式触发器允许我们非常灵活地指定作业的执行时间。
Quartz从入门到精通
Quartz核心概念:调度器、触发器、作业[谁什么时候干什么活]任务调度Quartz(!)为何需要任务调度?在web应用中,大多数任务是以一种"防止用户长时间等待"的方式完成的。
在Google搜索这样的例子中,减少等待时间对用户体验来说至关重要。
异步任务的一种解决方案是在用户提交后生成一个线程(来处理异步任务),但这也不能解决那些需要以一定时间间隔重复运行任务、或在每天的指定时间运行任务的情况。
让我们从一个数据库报表的例子来看看任务调度能如何帮助改善系统设计。
报表可能是错综复杂的,这取决于用户所需数据的种类,以及是否需要从一个或多个数据库收集大量数据。
用户可能需要很长时间来运行这样的"按需"报表。
因此,我们向这个报表示例中添加任务调度机制,以便用户可以安排在任何他们需要的时间生成报表,并以PDF或其他格式在email中发送。
用户可以让报表在每天的凌晨2:22,系统正处于低负荷时运行;也可以选择只在特定时间运行一次。
通过在报表应用中加入任务调度,我们可以为产品添加一项有用的功能,并改善用户体验。
幸运的是,有一个强大的开源解决方案可以让我们以标准的方式在web应用(或任何Java应用)中实施任务调度。
以下示例展示了在web应用中,如何使用Quartz来创建一个任务调度框架。
这个示例还使用了Struts Action framework 插件,以便在web应用启动时初始化任务调度机制。
Struts是最常见的MVC框架,为大多数开发人员所熟悉。
当然除此之外还有许多框架可以协助在web应用中实现MVC模式。
启动时初始化任务调度器我们首先要做的是建立一个Struts插件,让它在容器启动时创建我们的任务调度器。
在以下例子中,我们选择Tomcat作为web应用容器,不过这些示例在其他容器中也应当可以运行。
我们要创建一个Struts插件类,并在struts-config.xml中加入几行代码以使之可以工作。
Quartz的基本使用之入门(2.3.0版本)
Quartz的基本使⽤之⼊门(2.3.0版本)⼀、Quartz可以⽤来做什么Quartz是⼀个强⼤任务调度框架,我⼯作时候会在这些情况下使⽤到quartz框架,当然还有很多的应⽤场景,在这⾥只列举2个实际⽤到的餐厅系统会在每周四晚上的22点⾃动审核并⽣成报表⼈事系统会在每天早晨8点给有待办的⼈员⾃动发送Email提醒⼆、使⽤Quartz之前的准备1.建⽴⼀个Maven项⽬2.引⼊quartz的依赖 但然也可以使⽤这个2.3.0的依赖,下⾯的例⼦都是使⽤此依赖并实现了效果。
<!-- https:///artifact/org.quartz-scheduler/quartz --><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.0</version></dependency>三、编写第⼀个Quartz任务案例 - 每隔2秒钟打印⼀次HelloQuartz先实现⼀下这个基本的Quartz的任务再来介绍⼀下Quartz的3个重要组成,JobDetail,Trigger,Scheduler1.创建⼀个类 HelloJob.java,这个类是编写我们的具体要实现任务(打印Hello Quartz)import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import java.text.SimpleDateFormat;import java.util.Date;public class HelloJob implements Job{ public void execute(JobExecutionContext jobExecutionCo //打印当前的执⾏时间例如 2017-11-23 00:00:00Date date = new Date();SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println("现在的时间是:"+ sf.format(date));//具体的业务逻辑System.out.println("Hello Quartz");}}2.创建⼀个类HelloScheduler.java,这个是具体触发我们的任务public class HelloScheduler {public static void main(String[] args) throws SchedulerException {//创建⼀个jobDetail的实例,将该实例与HelloJob Class绑定JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).withIdentity("myJob").build();//创建⼀个Trigger触发器的实例,定义该job⽴即执⾏,并且每2秒执⾏⼀次,⼀直执⾏SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger").startNow().withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).repeatForever()).build();//创建schedule实例StdSchedulerFactory factory = new StdSchedulerFactory();Scheduler scheduler = factory.getScheduler();scheduler.start();scheduler.scheduleJob(jobDetail,trigger);}}3.执⾏main⽅法,Run 'HelloScheduler.main()',可以看见如下效果,表明任务执⾏成功了4.⼀句话看懂quartz1、创建调度⼯⼚(); //⼯⼚模式2、根据⼯⼚取得调度器实例(); //⼯⼚模式3、Builder模式构建⼦组件<Job,Trigger> // builder模式, 如JobBuilder、TriggerBuilder、DateBuilder4、通过调度器组装⼦组件调度器.组装<⼦组件1,⼦组件2...> //⼯⼚模式5、调度器.start(); //⼯⼚模式四、第⼆个案例 - 每⽇的9点40分触发任务打印HelloQuartz先上代码,然后介绍⼀下cron表达式⽣成规则。
Quartz2.2基础教程
Quartz2.2基础教程下载和安装如果是采用maven管理依赖,则依赖配置如下:[html] view plain copy print?<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.2.3</version> </dependency> <dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz-jobs</artifactId><version>2.2.3</version> </dependency> 如果不是的话,所需依赖包可以到官网下载/downloads/关键接口Scheduler一个scheduler的生命周期是有限的,从通过SchedulerFactory创建开始直到调用它的shutdown()方法。
scheduler接口一旦创建,就能添加、移除、和列出job和trigger,并执行另一些与调度相关的操作(例如暂停trigger),然而,在scheduler被start()方法启动前,它不会作用于任何trigger(执行job)。
Job一个job就是实现了Job接口的类。
如下所示,这个接口只有一个简单的方法:[java] viewplain copy print?package org.quartz; public interface Job { public void execute(JobExecutionContext context) throws JobExecutionException; } JobExecutionContext对象就是通过这个方法提供job实例的信息,如运行环境,包括scheduler执行的句柄,trigger 触发执行的句柄,job的JobDetail对象,和一些其它信息。
Quartz任务调度--详细教程
Quartz任务调度快速入门1概述各种企业应用几乎都会碰到任务调度的需求,就拿论坛来说:每隔半个小时生成精华文章的RSS文件,每天凌晨统计论坛用户的积分排名,每隔30分钟执行锁定用户解锁任务。
对于一个典型的MIS系统来说,在每月1号凌晨统计上个月各部门的业务数据生成月报表,每半个小时查询用户是否已经有快到期的待处理业务……,这样的例子俯拾皆是,不胜枚举。
任务调度本身涉及到多线程并发、运行时间规则制定和解析、场景保持与恢复、线程池维护等诸多方面的工作。
如果直接使用自定义线程这种刀耕火种的原始办法,开发任务调度程序是一项颇具挑战性的工作。
Java开源的好处就是:领域问题都能找到现成的解决方案。
OpenSymphony所提供的Quartz自2001年发布版本以来已经被众多项目作为任务调度的解决方案,Quartz在提供巨大灵活性的同时并未牺牲其简单性,它所提供的强大功能使你可以应付绝大多数的调度需求。
Quartz 在开源任务调度框架中的翘首,它提供了强大任务调度机制,难能可贵的是它同时保持了使用的简单性。
Quartz 允许开发人员灵活地定义触发器的调度时间表,并可以对触发器和任务进行关联映射。
此外,Quartz提供了调度运行环境的持久化机制,可以保存并恢复调度现场,即使系统因故障关闭,任务调度现场数据并不会丢失。
此外,Quartz还提供了组件式的侦听器、各种插件、线程池等功能。
了解Quartz体系结构Quartz对任务调度的领域问题进行了高度的抽象,提出了调度器、任务和触发器这3个核心的概念,并在org.quartz通过接口和类对重要的这些核心概念进行描述:●Job:是一个接口,只有一个方法void execute(JobExecutionContext context),开发者实现该接口定义运行任务,JobExecutionContext类提供了调度上下文的各种信息。
Job运行时的信息保存在 JobDataMap实例中;●JobDetail:Quartz在每次执行Job时,都重新创建一个Job实例,所以它不直接接受一个Job的实例,相反它接收一个Job实现类,以便运行时通过newInstance()的反射机制实例化Job。
Quartz学习资料
Quartz学习介绍QuartzQuartz是一个开源的任务调度系统,它能用来调度很多任务的执行。
运行环境Quartz 能嵌入在其他应用程序里运行。
Quartz 能在一个应用服务器里被实例化(或servlet容器), 并且参与XA事务Quartz能独立运行(通过JVM),或者通过RMIQuartz能被集群实例化任务调度当一个指定给任务的触发器发生时,任务就被调度执行. 触发器能被创建为:一天的某个时间(精确到毫秒级)一周的某些天一个月的某些天一年的某些天不在一个Calendar列出的某些天 (例如工作节假日)在一个指定的次数重复重复到一个指定的时间/日期无限重复在一个间隔内重复能够给任务指定名称和组名.触发器也能够指定名称和组名,这样可以很好的在调度器里组织起来.一个加入到调度器里的任务可以被多个触发器注册。
在J2EE环境里,任务能作为一个分布式(XA)事务的一部分来执行。
任务执行任务能够是任何实现Job接口的Java类。
任务类能够被Quartz实例化,或者被你的应用框架。
当一个触发器触发时,调度器会通知实例化了JobListener 和TriggerListener 接口的0个或者多个Java对象(监听器可以是简单的Java对象, EJBs, 或JMS发布者等). 在任务执行后,这些监听器也会被通知。
当任务完成时,他们会返回一个JobCompletionCode ,这个代码告诉调度器任务执行成功或者失败.这个代码也会指示调度器做一些动作-例如立即再次执行任务。
任务持久化Quartz的设计包含JobStore接口,这个接口能被实现来为任务的存储提供不同的机制。
应用JDBCJobStore, 所有被配置成“稳定”的任务和触发器能通过JDBC存储在关系数据库里。
应用RAMJobStore, 所有任务和触发器能被存储在RAM里因此不必在程序重起之间保存-一个好处就是不必使用数据库。
事务使用JobStoreCMT(JDBCJobStore的子类),Quartz 能参与JTA事务。
Quartz快速入门
使用Quartz与Spring把crontab架设到你的应用服务器中By Neowang问题的提出候选解决方案Quartzantlr-2.7.2.jaraopalliance-1.0.jaraspectjrt.jaraspectjweaver.jarclassworlds-1.1.jarcommons-beanutils-1.7.0.jarcommons-chain-1.2.jarcommons-collections-3.2.jarcommons-dbcp.jarcommons-digester-2.0.jarcommons-fileupload-1.2.1.jarcommons-httpclient-3.1.jarcommons-io-1.3.2.jarcommons-lang-2.3.jarcommons-logging-1.0.4.jar commons-logging-api-1.1.jar commons-pool.jarcommons-validator-1.3.1.jardwr.jarezmorph-1.0.6.jarfreemarker-2.3.15.jarganymed-ssh2-build210.jargwt-servlet.jargwt-user.jaribatis-2.3.4.726.jarjson-lib-2.1.jarjunit-4.8.2.jarlog4j.jarmail.jarmysql-connector-java-5.1.13-bin.jar ognl-2.7.3.jaroro-2.0.8.jarpoi-3.6-20091214.jarspring-core.jarspring-ibatis.jarspring-web.jarspring.jarsslext-1.2-0.jarStatistics.jarstruts2-convention-plugin-2.1.8.1.jarstruts2-core-2.1.8.1.jarstruts2-embeddedjsp-plugin-2.1.8.1.jarstruts2-json-plugin-2.1.8.1.jarstruts2-spring-plugin-2.1.8.1.jarstruts2gwtplugin-1.02.jarvelocity-1.5.jarvelocity-tools-1.3.jarxwork-core-2.1.6.jar目前竞价广告中DWR的使用是基于注解方式配置的, DWR官网上的Demo是基于dwr.xml文件方式配置进行的, 所以我不再重复讲解文件方式的配置,希望了解配置方式的同学直接到官方上学习:假如你的项目已经存在Struts, Spring的配置,请特别关注一下红色部分DWR的配置项目配置文件(web.xml)配置文件:<?xml version="1.0"encoding="UTF-8"?><web-app xmlns:xsi="/2001/XMLSchema-instance" xmlns="/xml/ns/javaee"xmlns:web="/xml/ns/javaee/web-app_2_5.xsd"xsi:schemaLocation="/xml/ns/javaee/xml/ns/javaee/web-app_2_5.xsd"version="2.5"> <context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring*.xml</param-value> </context-param><listener><listener-class>org.springframework.web.context.ContextLoaderList ener</listener-class></listener><filter><filter-name>struts2</filter-name><filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepa reAndExecuteFilter</filter-class><init-param><param-name>config</param-name><param-value>struts-default.xml,struts-plugin.xml,struts.xml</par am-value></init-param></filter><filter-mapping><filter-name>struts2</filter-name><url-pattern>/*</url-pattern></filter-mapping><welcome-file-list><welcome-file>stone/login.jsp</welcome-file></welcome-file-list><login-config><auth-method>BASIC</auth-method></login-config><!--由Sprng载入的Log4j配置文件位置--><context-param><param-name>log4jConfigLocation</param-name><param-value>/WEB-INF/classes/log4j.properties</param-value></context-param><!--Spring log4j Config loader--><listener><listener-class>org.springframework.web.util.Log4jConfigListen er</listener-class></listener><!-- DWR配置开始 --><servlet><servlet-name>dwr-invoker</servlet-name><servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class><init-param><param-name>activeReverseAjaxEnabled</param-name><param-value>true</param-value></init-param><init-param><param-name>debug</param-name><param-value>true</param-value></init-param><init-param><param-name>classes</param-name><param-value>com.soso.stone.dwr.exflow.MyTest,com.soso.stone.dwr.exstat.ZXDService</param-value></init-param></servlet><servlet-mapping><servlet-name>dwr-invoker</servlet-name><url-pattern>/dwr/*</url-pattern></servlet-mapping><!-- DWR配置结束 --></web-app>Spring(applicationContext.xml)配置文件:请关注红色部分指明的自动扫描路径, 注解方式可以免去Spring的大部分配置<?xml version="1.0"encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:context="/schema/context"xmlns:aop="/schema/aop"xmlns:tx="/schema/tx"xsi:schemaLocation="/schema/bean s/schema/beans/spring-beans-2.5.xsd /schema/context/schema/context/spring-context-2.5. xsd/schema/aop/schema/aop/spring-aop-2.5.xsd/schema/tx/schema/tx/spring-tx-2.5.xsd"><context:annotation-config /><context:component-scan base-package="com.soso" /></beans>struts(struts.xml)配置文件:Struts的配置通常不会影响DWR, 这里省略了DWR(DwrTest.java)测试类:package com.soso.stone.dwr.exstat;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional; import org.springframework.stereotype.Service;import org.directwebremoting.spring.SpringCreator;import org.directwebremoting.annotations.Param;import org.directwebremoting.annotations.RemoteProxy;import org.directwebremoting.annotations.RemoteMethod;import org.directwebremoting.annotations.RemoteProperty;import org.directwebremoting.convert.BeanConverter;import javax.annotation.Resource;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service;@Service("DwrTest")@RemoteProxy(creator = SpringCreator.class, name = "DwrTest", creatorParams = @Param(name = "beanName", value = "DwrTest"))public class DwrTest{@RemoteMethodpublic String test (String str){System.out.println ("你好") ;return "竞价广告:"+ str;}}JSP测试文件(default.jsp):<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "/TR/html4/loose.dtd "><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>测试DWR</title><script type='text/javascript'src='${pageContext.request.contextPath }/dwr/interface/DwrTest.js'></scrip t><script type='text/javascript'src='${pageContext.request.contextPath }/dwr/engine.js'></script><script type='text/javascript'src='${pageContext.request.contextPath }/dwr/util.js'></script></head><body><a href="javascript:onTest();">测试DWR!</a></body><script type="text/javascript">function onTest(){dwrTest.test("测试数据!", function(data){alert(data);});}</script></html>关于不同数据类型的传递方法Js中array可以被转译为Arrayliet, 静态数组Js中对象可以对应HashMap如{name:"neowang", age:"28"} 对应<String, String>的hashmapJava中HasMap对应Js中的对象, 如:HashMap<Integer, <String, String>>的hash表对应Js对象为{1:{name:"neowang",cname:"王宇"},2:{name:"jessychen", cname:"陈洁瑶"},3:{...}....}。
Quartz入门与提高2
JOB状态
StatefulJob——有状态任务 现在,一些关于Job状态数据的附加论题:一个Job实例 可以被定义为“有状态的”或者“无状态的”。“无状态 的”任务只拥有它们被加入到scheduler时所存储的 JobDataMap。这意味着,在执行任务过程中任何对Job Data Map所作的更改都将丢失而且任务下次执行时也无 法看到。你可能会猜想出,有状态的任务恰好相反,它在 任务的每次执行之后重新存储JobDataMap。有状态任务 的一个副作用就是它不能并发执行。换句话说,如果任务 有状态,那么当触发器在这个任务已经在执行的时候试图 触发它,这个触发器就会被阻塞(等待),直到前面的执 行完成。 想使任务有状态,它就要实现StatefulJob接口而不是实 现Job接口。
此处填写章节名称
在所实现的类成为真正的“Job‖时,期望任务所具 有的各种属性需要通知给Quartz。通过 JobDetail类可以完成这个工作,这个类在前面的 章节中曾简短提及过。软件“考古学家”们可能 对了解Quartz早期版本的样子感兴趣。早期的 Quartz中,JobDetail实现的功能被强加给实现 Job的类,实现Job的类必须实现Job接口中所有 同JobDetail类一样的'getter'方法。这样为每个 Job类强加了一个重新实现虚拟识别码的笨重工 作,这实在糟糕,因此,我们创建了JobDetail类。
JobDataMap
大多数时候我们需要向job传递一些参数。这些参数需要保 存在JobDataMap中。 JobDataMap被用来保存一系列的(序列化的)对象,这些 对象在Job执行时可以得到。JobDataMap是Java Map 接口的一个实现,而且还增加了一些存储和读取主类型数 据的便捷方法。 注意:这里保存的数据必须是序列化的。 quartz.properties中可以设置一个属性标识传递给 JobDataMap的信息只能是字符串。而我们使用 JobDataMap的时候最好不要传递类对象信息。
Quartz入门使用
Quartz使用(一)-入门使用很久没有用Quartz了,居然忘记如何使用了,这里赶紧记录下对Quartz就不说明了,直接上代码注:这里使用的是Quartz1.5.2版本(包:quartz-1.5.2.jar)简单的任务管理类import java.text.ParseException;import org.quartz.CronTrigger;import org.quartz.Job;import org.quartz.JobDetail;import org.quartz.Scheduler;import org.quartz.SchedulerException;import org.quartz.SchedulerFactory;import org.quartz.Trigger;import org.quartz.impl.StdSchedulerFactory;/*** @Title:Quartz管理类** @Description:** @Copyright:* @author zz 2008-10-8 14:19:01* @version 1.00.000**/public class QuartzManager {private static SchedulerFactory sf =new StdSchedulerFactory();private static String JOB_GROUP_NAME = "group1";private static String TRIGGER_GROUP_NAME = "trigger1";/*** 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名* @param jobName 任务名* @param job 任务* @param time 时间设置,参考quartz说明文档* @throws SchedulerException* @throws ParseException*/public static void addJob(String jobName,Job job,String time)throws SchedulerException, ParseException{Scheduler sched = sf.getScheduler();JobDetail jobDetail =new JobDetail(jobName, JOB_GROUP_NAME, job.get Class());//任务名,任务组,任务执行类//触发器CronTrigger trigger =new CronTrigger(jobName, TRIGGER_GROUP_NAME);//触发器名,触发器组trigger.setCronExpression(time);//触发器时间设定sched.scheduleJob(jobDetail,trigger);//启动if(!sched.isShutdown())sched.start();}/*** 添加一个定时任务* @param jobName 任务名* @param jobGroupName 任务组名* @param triggerName 触发器名* @param triggerGroupName 触发器组名* @param job 任务* @param time 时间设置,参考quartz说明文档* @throws SchedulerException* @throws ParseException*/public static void addJob(String jobName,String jobGroupName,String triggerName,String triggerGroupName,Job job,String tim e)throws SchedulerException, ParseException{Scheduler sched = sf.getScheduler();JobDetail jobDetail =new JobDetail(jobName, jobGroupName, job.getClass ());//任务名,任务组,任务执行类//触发器CronTrigger trigger =new CronTrigger(triggerNam e, triggerGroupName);//触发器名,触发器组trigger.setCronExpression(time);//触发器时间设定sched.scheduleJob(jobDetail,trigger);if(!sched.isShutdown())sched.start();}/*** 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名)* @param jobName* @param time* @throws SchedulerException* @throws ParseException*/public static void modifyJobTim e(String jobName,String tim e)throws SchedulerException, ParseException{Scheduler sched = sf.getScheduler();Trigger trigger = sched.getTrigger(jobName,TRIGGER_GROUP_NAME);if(trigger != null){CronTrigger ct = (CronTrigger)trigger;ct.setCronExpression(time);sched.resum eTrigger(jobName,TRIGGER_GROUP_NAME);}}/*** 修改一个任务的触发时间* @param triggerName* @param triggerGroupName* @param time* @throws SchedulerException* @throws ParseException*/public static void m odifyJobTime(String triggerName,String triggerGroupName,String time)throws SchedulerException, ParseException{Scheduler sched = sf.getScheduler();Trigger trigger = sched.getTrigger(triggerName,triggerGroupName);if(trigger != null){CronTrigger ct = (CronTrigger)trigger;//修改时间ct.setCronExpression(time);//重启触发器sched.resum eTrigger(triggerName,triggerGroupName);}}/*** 移除一个任务(使用默认的任务组名,触发器名,触发器组名)* @param jobName* @throws SchedulerException*/public static void rem oveJob(String jobName)throws SchedulerException{Scheduler sched = sf.getScheduler();sched.pauseTrigger(jobName,TRIGGER_GROUP_NAME);//停止触发器sched.unscheduleJob(jobName,T RIGGER_GROUP_NAME);//移除触发器sched.deleteJob(jobName,JOB_GROUP_NAME);//删除任务}/*** 移除一个任务* @param jobName* @param jobGroupName* @param triggerName* @param triggerGroupName* @throws SchedulerException*/public static void rem oveJob(String jobName,String jobGroupName,String triggerName,String triggerGroupName)throws SchedulerException{Scheduler sched = sf.getScheduler();sched.pauseTrigger(triggerName,triggerGroupName);//停止触发器sched.unscheduleJob(triggerName,triggerGroupName);//移除触发器sched.deleteJob(jobName,jobGroupNam e);//删除任务}}测试工作类import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;public class TestJob implements Job {public void execute(JobExecutionContext arg0) throws JobExecutionExcepti on {// TODO Auto-generated m ethod stubSystem.out.println("★★★★★★★★★★★");}}测试类public class QuartzTest {/*** @param args*/public static void m ain(String[] args) {// TODO Auto-generated m ethod stubTestJob job =new TestJob();String job_name ="11";try {System.out.println("【系统启动】");QuartzManager.addJob(job_name,job,"0/5 * * * * ?");Thread.sleep(10000);System.out.println("【修改时间】");QuartzManager.modifyJobTime(job_name,"0/10 * * * * ?");Thread.sleep(20000);System.out.println("【移除定时】");QuartzManager.removeJob(job_name);Thread.sleep(10000);System.out.println("\n【添加定时任务】");QuartzManager.addJob(job_name,job,"0/5 * * * * ?");} catch (Exception e) {e.printStackTrace();}}}使用Quartz实现作业调度(二)来源:小熊时间:2008-08-05 16:10 字体:[大中小] 收藏我要投稿前面使用了Quartz 1.6来实现作业调度,但是只能指定运行的次数,在实际运用中就有些不足了。
详细讲解Quartz如何从入门到精通
详细讲解Quartz如何从入门到精通Quartz是一个开源的作业调度框架,它完全由Java写成,并设计用于J2SE和J2EE应中。
它提供了巨大的灵活性而不牺牲简单性。
你能够用它来为执行一个作业而创建简单的或复杂的调度。
它有很多特征,如:数据库支持,集群,插件,EJB作业预构建,JavaMail 及其它,支持cron-like表达式等等。
你曾经需要应用执行一个任务吗?这个任务每天或每周星期二晚上11:30,或许仅仅每个月的最后一天执行。
一个自动执行而无须干预的任务在执行过程中如果发生一个严重错误,应用能够知到其执行失败并尝试重新执行吗?你和你的团队是用Java编程吗?如果这些问题中任何一个你回答是,那么你应该使用Quartz调度器。
旁注:Matrix目前就大量使用到了Quartz。
比如,排名统计功能的实现,在Jmatrix 里通过Quartz定义了一个定时调度作业,在每天凌晨一点,作业开始工作,重新统计大家的Karma和排名等。
还有,RSS文件的生成,也是通过Quartz定义作业,每隔半个小时生成一次RSS XML文件。
Quartz让作业调度简单Quartz是一个完全由Java编写的开源作业调度框架。
不要让作业调度这个术语吓着你。
尽管Quartz框架整合了许多额外功能,但就其简易形式看,你会发现它易用得简直让人受不了!。
简单地创建一个实现org.quartz.Job接口的Java类。
Job接口包含唯一的方法:在你的Job接口实现类里面,添加一些逻辑到execute()方法。
一旦你配置好Job实现类并设定好调度时间表,Quartz将密切注意剩余时间。
当调度程序确定该是通知你的作业的时候,Quartz框架将调用你Job实现类(作业类)上的execute()方法并允许做它该做的事情。
无需报告任何东西给调度器或调用任何特定的东西。
仅仅执行任务和结束任务即可。
如果配置你的作业在随后再次被调用,Quartz框架将在恰当的时间再次调用它。
quartz使用方法
quartz使用方法【原创实用版3篇】目录(篇1)1.介绍 Quartz2.Quartz 的基本使用方法3.Quartz 的高级使用方法4.Quartz 的优点与局限性正文(篇1)Quartz 是一种常用的时间任务调度框架,它允许用户在特定的时间间隔或特定的时间点执行任务。
Quartz 具有丰富的功能和强大的灵活性,可以满足各种复杂的调度需求。
下面,我们将详细介绍 Quartz 的使用方法。
一、Quartz 的基本使用方法1.添加依赖在使用 Quartz 之前,首先需要在项目中引入 Quartz 的依赖。
在Maven 项目中,可以在 pom.xml 文件中添加以下依赖:```xml<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.2</version></dependency>```2.创建 Job创建一个实现 org.quartz.Job 接口的类,并实现 execute 方法。
execute 方法中的代码将在任务执行时被调用。
```javapublic class MyJob implements Job {@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {System.out.println("任务执行,时间:" + new Date());}}```3.配置 Job 和 Trigger创建 Job 之后,还需要创建一个 Trigger 来触发 Job 的执行。
Trigger 接口有多个实现类,如 SimpleTrigger 和 CronTrigger,可以根据需要选择合适的实现类。
Quartz框架快速入门
Quartz快速入门一创建一个Java工程,引入几个JAR到工程中才能成功构建它们。
首先,你需要Quartz的二进制版本,包的名字是quartz-<version>.jar。
Quartz还需要几个第三方库;这依赖于你要用到框架的什么功能而定,Commons Digester库可以在<QUARTZ_HOME>/lib/core和<QUARTZ_HOME>/lib/optional目录中找到。
如果出现ng.NoClassDefFoundError: javax/transaction/UserTransaction的错误,解决办法是:引入jta.jar包,这个包在quartz-1.6.0/lib/build下。
·创建一个Quartz Job类每一个Quartz Job必须有一个实现了org.quartz.Job接口的具体类。
这个接口仅有一个要你在Job中实现的方法,execute(),方法execute()的原型如下:public void execute(JobExecutionContext context) throws JobExecutionException;当Quartz调度器确定到时间要激发一个Job的时候,它就会生成一个Job实例,并调用这个实例的execute()方法。
调度器只管调用execute()方法,而不关心执行的结果,除了在作业执行中出问题抛出的org.quartz.JobExecutionException异常。
下面是我们的第一个Quartz job,它被设计来扫描一个目录中的文并显示文件的详细信息。
package com.vista.quartz;import java.io.File;import java.io.FileFilter;import java.util.Date;import mons.logging.Log;import mons.logging.LogFactory;import org.quartz.Job;import org.quartz.JobDataMap;import org.quartz.JobDetail;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;public class ScanDirectoryJob implements Job{static Log logger = LogFactory.getLog(ScanDirectoryJob.class);//日志记录器public void execute(JobExecutionContext context) throws JobExecutionExcept ion{//Every job has its own job detailJobDetail jobDetail = context.getJobDetail();// The name is defined in the job definitionString jobName = jobDetail.getName();//任务名称// Log the time the job started(jobName + " fired at " + new Date());//记录任务开始执行的时间// The directory to scan is stored in the job mapJobDataMap dataMap = jobDetail.getJobDataMap();//任务所配置的数据映射表String dirName = dataMap.getString("SCAN_DIR");//获取要扫描的目录// Validate the required inputif (dirName == null){//所需要的扫描目录没有提供throw new JobExecutionException( "Directory not configured" );}// Make sure the directory existsFile dir = new File(dirName);if (!dir.exists()){//提供的是错误目录throw new JobExecutionException( "Invalid Dir "+ dirName);}// Use FileFilter to get only XML filesFileFilter filter = new FileExtensionFileFilter(".xml");//只统计xml文件File[] files = dir.listFiles(filter);if (files == null || files.length <= 0){//目录下没有xml文件("No XML files found in " + dir);// Return since there were no filesreturn;}// The number of XML filesint size = files.length;// Iterate through the files foundfor (int i = 0; i < size; i++){File file = files[i];// Log something interesting about each file.File aFile = file.getAbsoluteFile();long fileSize = file.length();String msg = aFile + " - Size: " + fileSize;(msg);//记录下文件的路径和大小}}}当Quartz 调用execute()方法,会传递一个org.quartz.JobExecutionContext上下文变量,里面封装有Quartz的运行时环境和当前正执行的Job。
Quartz教程
Quartz教程作者:王兵旺1. 概述本文讲述quatrz如何应用在一个项目中,随着这篇文章的节奏,你安全可以掌握quatrz的使用。
此文能够帮助你快速的入门。
2. Quartz介绍Quartz大约有300个java类和接口,并被组织到12个包中。
它的核心功能点如下2.1 Quartz调度器Quartz框架的核心是调度器。
调度器负责管理Quartz应用运行时环境。
调度器不是靠自己做所有的工作,而是依赖框架内一些非常重要的部件。
Quartz不仅仅是线程和线程管理。
为确保可伸缩性,Quartz采用了基于多线程的架构。
启动时,框架初始化一套worker线程,这套线程被调度器用来执行预定的作业。
这就是Quartz怎样能并发运行多个作业的原理。
Quartz依赖一套松耦合的线程池管理部件来管理线程环境。
2.2 Quartz作业用Quartz的行话讲,作业是一个执行任务的简单java类。
任务可以是任何java代码。
只需你实现org.quartz.Job接口并且在出现严重错误情况下抛出JobExecutionException异常即可。
Job接口包含唯一的一个方法execute(),作业从这里开始执行。
一旦实现了Job接口和execute()方法,当Quartz确定该是作业运行的时候,它将调用你的作业。
Execute()方法内就完全是你要做的事情。
2.3 Quartz作业管理和存储作业一旦被调度,调度器需要记住并且跟踪作业和它们的执行次数。
作业执行需要非常准确和即时调用在被调度作业上的execute()方法。
Quartz通过一个称之为作业存储(JobStore)的概念来做作业存储和管理。
2.4 Quartz有效作业存储Quartz提供两种基本作业存储类型。
第一种类型叫做RAMJobStore,它利用通常的内存来持久化调度程序信息。
这种作业存储类型最容易配置、构造和运行。
对许多应用来说,这种作业存储已经足够了。
然而,因为调度程序信息是存储在被分配给JVM的内存里面,所以,当应用程序停止运行时,所有调度信息将被丢失。
quartz用法
quartz用法Quartz是一个流行的Java调度框架,它允许开发人员创建基于时间的作业,例如定期执行任务、发送电子邮件等。
Quartz提供了许多功能,包括可靠性、灵活性和可扩展性。
本文将介绍Quartz的用法,包括安装、配置、创建作业和触发器以及使用监听器和集群。
一、安装1. 下载Quartz您可以从Quartz官方网站下载最新版本的Quartz。
解压缩下载后的文件,并将其放置在您选择的位置。
2. 添加依赖项在您的Java项目中添加以下依赖项:```xml<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.2</version></dependency>```3. 创建数据库表Quartz需要一个数据库来存储作业和触发器信息。
您可以使用提供的SQL脚本来创建表或手动创建表。
请注意,不同版本的Quartz可能需要不同版本的SQL脚本。
二、配置1. 创建调度器在Java代码中创建调度器对象:```javaSchedulerFactory schedulerFactory = new StdSchedulerFactory(); Scheduler scheduler = schedulerFactory.getScheduler();```2. 配置数据源如果您选择使用数据库存储作业和触发器信息,则需要配置数据源。
以下是一个示例:```xml<bean id="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDat aSource"><property name="driverClassName"value="com.mysql.jdbc.Driver"/><property name="url"value="jdbc:mysql://localhost:3306/quartz"/><property name="username" value="root"/><property name="password" value=""/></bean>```3. 配置作业和触发器使用以下代码配置作业和触发器:```javaJobDetail job =JobBuilder.newJob(MyJob.class).withIdentity("myJob").build();Trigger trigger =TriggerBuilder.newTrigger().withIdentity("myTrigger").withSchedule(SimpleScheduleBuilder.repeatSecondlyForev er(10)).build();scheduler.scheduleJob(job, trigger);```三、创建作业和触发器1. 创建作业创建一个实现org.quartz.Job接口的类,例如:```javapublic class MyJob implements Job {@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {// 执行任务}}```2. 创建触发器Quartz提供了许多类型的触发器,包括SimpleTrigger、CronTrigger、CalendarIntervalTrigger等。
Quartz指南HarriesBlog?
Quartz指南HarriesBlog™Quartz是一个开源的任务调度系统,它能用来调度很多任务的执行。
它完全由Java写成,并设计用于J2SE和J2EE应用中。
它提供了巨大的灵活性而不牺牲简单性。
你能够用它来为执行一个作业而创建简单的或复杂的调度。
它有很多特征,如:数据库支持,集群,插件,EJB作业预构建,JavaMail及其它,支持cron-like表达式等等。
1.介绍Quartz1.运行环境2.任务调度3.任务执行4.任务持久化5.事务6.集群7.监听器和插件2.使用Quartz3.J obs 和 Triggers4.更多关于Jobs JobDetails1.JobDataMap2.StatefulJob3.Job Instances4.job的其他属性5.JobExecutionException5.更多关于Triggers1.Calendars2.不触发misfire指令3.TriggerUtils – Triggers Made Easy4.TriggerListeners6.S impleTrigger1.SimpleTrigger 不触发指令7.C ronTrigger1.构造器2.克隆表达式3.特殊字符4.一些例子5.注意8.T riggerListeners 和JobListeners 1.使用Listeners9.S chedulerListeners10.JobStores1.RAMJobStore2.JDBCJobStore11.配置资源使用和调度器工厂1.StdSchedulerFactory2.DirectSchedulerFactory3.Logging12.高级企业特性1.集群2.JTA 事务13.Quartz 的其他特性1.Plug-Ins2.JobFactory3.Jobs工具14.配置文件里配置项总结1.设置主要调度器2.设置线程池3.设置全局监听器4.设置Plugins5.设置RMI6.设置RAMJobStore7.设置JDBC-JobStoreTX8.设置JDBC-JobStoreCMT9.设置数据源10.设置集群15.在Web应用中用Quartz1.初始化调度器2.访问调度器16.FAQ。
作业调度框架Quartz.NET2.0入门(Quartz2.0C#)
作业调度框架2.0入门(Quartz2.0C#)注:目前网上诸多介绍的文章,甚至官网上的Tutorial都是1.0版本的,而这个项目在2.0版本对项目进行了比较大规模的修改,使得原有的很多例子都不能运行,故写此文。
由于本人是边学边用,加之技术写作水平皆有限,错误自然难免,望轻拍,我将不定时更新完善此贴,希望能为需要的朋友提供帮助。
1. 项目介绍和其他绝大多数开源项目一样也包含了其他几个优秀的开源项目:核心 ----Common.Logging(通用日志接口)----C5(泛型集合类)示例程序----log4net(日志记录-通用日志接口实现)----topshelf(跨平台服务宿主程序)使用的许可是Apache License,商业友好,使用者可以修改源码用于开源或商业项目,只需包含许可及修改说明。
2. 开发思路我们来了解下中常用的几个概念:Scheduler ---------主调度程序 --------- Quartz核心Job ---------作业 --------- 服务要做的(业务操作)Trigger ---------触发器 --------- 服务执行条件(何时执行操作)Listener ---------事件监听器 --------- 执行期事件(Job执行前后/ Scheduler启动终止暂停时应该做什么,可以挂一些特定事件)了解了这些概念之后,我们就可以组合这些概念并整理出开发的思路:先利用SchedulerFactory构建一个Scheduler,启动Scheduler,之后构建Job和Trigger,若有作业监听需求,在Listener上添加相应的处理程序,再将Job和Trigger关联后放入Scheduler3. 的简单使用1. 新建一个控制台程序,引用Quartz.dll和Common.Logging.dll2. 新建一个类,命名为SampleJob,继承并实现接口Quartz.IJobpublic class SampleJob : IJob{public void Execute(IJobExecutionContext context){File.AppendAllText("C:\\Quartz.txt", "SampleJob Is Run");File.AppendAllText("C:\\Quartz.txt",Environment.NewLine);}}3.在Program.cs的main方法中写如下代码后运行这个控制台会程序会发现已经SampleJob中的Execute方法已经执行ISchedulerFactory factory = new StdSchedulerFactory();IScheduler scheduler = factory.GetScheduler();scheduler.Start();IJobDetail job = JobBuilder.Create<SampleJob>().WithIdentity("SampleJob", "JobGroup1").Build();ITrigger trigger =TriggerBuilder.Create().StartNow().Build();scheduler.ScheduleJob(job, trigger);4. 使用topshelf创建WINDOWS服务也许有的网友会疑问,以控制台程序作为服务宿主还没有意义的,这时轮到Topshelf出场了,使用它可以很方便的构建跨平台服务寄主,而在调试时直接以控制台的形式运行即可,非常方便。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Quartz任务调度快速入门概述各种企业应用几乎都会碰到任务调度的需求,就拿论坛来说:每隔半个小时生成精华文章的RSS文件,每天凌晨统计论坛用户的积分排名,每隔30分钟执行锁定用户解锁任务。
对于一个典型的MIS系统来说,在每月1号凌晨统计上个月各部门的业务数据生成月报表,每半个小时查询用户是否已经有快到期的待处理业务……,这样的例子俯拾皆是,不胜枚举。
任务调度本身涉及到多线程并发、运行时间规则制定和解析、场景保持与恢复、线程池维护等诸多方面的工作。
如果直接使用自定义线程这种刀耕火种的原始办法,开发任务调度程序是一项颇具挑战性的工作。
Java开源的好处就是:领域问题都能找到现成的解决方案。
OpenSymphony所提供的Quartz自2001年发布版本以来已经被众多项目作为任务调度的解决方案,Quartz在提供巨大灵活性的同时并未牺牲其简单性,它所提供的强大功能使你可以应付绝大多数的调度需求。
Quartz 在开源任务调度框架中的翘首,它提供了强大任务调度机制,难能可贵的是它同时保持了使用的简单性。
Quartz 允许开发人员灵活地定义触发器的调度时间表,并可以对触发器和任务进行关联映射。
此外,Quartz提供了调度运行环境的持久化机制,可以保存并恢复调度现场,即使系统因故障关闭,任务调度现场数据并不会丢失。
此外,Quartz还提供了组件式的侦听器、各种插件、线程池等功能。
了解Quartz体系结构Quartz对任务调度的领域问题进行了高度的抽象,提出了调度器、任务和触发器这3个核心的概念,并在org.quartz通过接口和类对重要的这些核心概念进行描述:●Job:是一个接口,只有一个方法void execute(JobExecutionContext context),开发者实现该接口定义运行任务,JobExecutionContext类提供了调度上下文的各种信息。
Job运行时的信息保存在 JobDataMap实例中;●JobDetail:Quartz在每次执行Job时,都重新创建一个Job实例,所以它不直接接受一个Job的实例,相反它接收一个Job实现类,以便运行时通过newInstance()的反射机制实例化Job。
因此需要通过一个类来描述Job的实现类及其它相关的静态信息,如Job名字、描述、关联监听器等信息,JobDetail 承担了这一角色。
通过该类的构造函数可以更具体地了解它的功用:JobDetail(ng.String name, ng.String group, ng.Class jobClass),该构造函数要求指定Job的实现类,以及任务在Scheduler中的组名和Job名称;●Trigger:是一个类,描述触发Job执行的时间触发规则。
主要有SimpleTrigger 和CronTrigger这两个子类。
当仅需触发一次或者以固定时间间隔周期执行,SimpleTrigger是最适合的选择;而CronTrigger则可以通过Cron表达式定义出各种复杂时间规则的调度方案:如每早晨9:00执行,周一、周三、周五下午5:00执行等;●Calendar:org.quartz.Calendar和java.util.Calendar不同,它是一些日历特定时间点的集合(可以简单地将org.quartz.Calendar看作java.util.Calendar的集合——java.util.Calendar代表一个日历时间点,无特殊说明后面的Calendar即指org.quartz.Calendar)。
一个Trigger可以和多个Calendar关联,以便排除或包含某些时间点。
假设,我们安排每周星期一早上10:00执行任务,但是如果碰到法定的节日,任务则不执行,这时就需要在Trigger触发机制的基础上使用 Calendar进行定点排除。
针对不同时间段类型,Quartz在org.quartz.impl.calendar包下提供了若干个Calendar 的实现类,如AnnualCalendar、MonthlyCalendar、WeeklyCalendar分别针对每年、每月和每周进行定义;●Scheduler:代表一个Quartz的独立运行容器,Trigger和JobDetail可以注册到Scheduler中,两者在 Scheduler中拥有各自的组及名称,组及名称是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实例;Quartz任务调度快速入门2●ThreadPool:Scheduler使用一个线程池作为任务运行的基础设施,任务通过共享线程池中的线程提高运行效率。
Job有一个StatefulJob子接口,代表有状态的任务,该接口是一个没有方法的标签接口,其目的是让Quartz知道任务的类型,以便采用不同的执行方案。
无状态任务在执行时拥有自己的JobDataMap拷贝,对JobDataMap的更改不会影响下次的执行。
而有状态任务共享共享同一个 JobDataMap实例,每次任务执行对JobDataMap所做的更改会保存下来,后面的执行可以看到这个更改,也即每次执行任务后都会对后面的执行发生影响。
正因为这个原因,无状态的Job可以并发执行,而有状态的StatefulJob不能并发执行,这意味着如果前次的StatefulJob还没有执行完毕,下一次的任务将阻塞等待,直到前次任务执行完毕。
有状态任务比无状态任务需要考虑更多的因素,程序往往拥有更高的复杂度,因此除非必要,应该尽量使用无状态的Job。
如果Quartz使用了数据库持久化任务调度信息,无状态的JobDataMap仅会在Scheduler注册任务时保持一次,而有状态任务对应的JobDataMap在每次执行任务后都会进行保存。
Trigger自身也可以拥有一个JobDataMap,其关联的Job可以通过JobExecutionContext#getTrigger().getJobDataMap()获取Trigger中的JobDataMap。
不管是有状态还是无状态的任务,在任务执行期间对Trigger的JobDataMap所做的更改都不会进行持久,也即不会对下次的执行产生影响。
Quartz拥有完善的事件和监听体系,大部分组件都拥有事件,如任务执行前事件、任务执行后事件、触发器触发前事件、触发后事件、调度器开始事件、关闭事件等等,可以注册相应的监听器处理感兴趣的事件。
图1描述了Scheduler的内部组件结构,SchedulerContext提供Scheduler全局可见的上下文信息,每一个任务都对应一个JobDataMap,虚线表达的JobDataMap表示对应有状态的任务:图1 Scheduler结构图一个Scheduler可以拥有多个Triger组和多个JobDetail组,注册Trigger和JobDetail时,如果不显式指定所属的组,Scheduler将放入到默认组中,默认组的组名为Scheduler.DEFAULT_GROUP。
组名和名称组成了对象的全名,同一类型对象的全名不能相同。
Scheduler本身就是一个容器,它维护着Quartz的各种组件并实施调度的规则。
Scheduler还拥有一个线程池,线程池为任务提供执行线程——这比执行任务时简单地创建一个新线程要拥有更高的效率,同时通过共享节约资源的占用。
通过线程池组件的支持,对于繁忙度高、压力大的任务调度,Quartz将可以提供良好的伸缩性。
提示: Quartz完整下载包examples目录下拥有10多个实例,它们是快速掌握Quartz应用很好的实例。
使用SimpleTriggerSimpleTrigger拥有多个重载的构造函数,用以在不同场合下构造出对应的实例:●SimpleTrigger(String name, String group):通过该构造函数指定Trigger 所属组和名称;●Si mpleTrigger(String name, String group, Date startTime):除指定Trigger所属组和名称外,还可以指定触发的开发时间;●SimpleTrigger(String name, String group, Date startTime, Date endTime, int repeatCount, long repeatInterval):除指定以上信息外,还可以指定结束时间、重复执行次数、时间间隔等参数;●SimpleTrigger(String na me, String group, String jobName, String jobGroup, Date startTime, Date endTime, int repeatCount, long repeatInterval):这是最复杂的一个构造函数,在指定触发参数的同时,还通过jobGroup和jobName,让该Trigger和 Scheduler中的某个任务关联起来。
通过实现 org.quartz..Job 接口,可以使 Java 类化身为可调度的任务。
代码清单1提供了 Quartz 任务的一个示例:代码清单1 SimpleJob:简单的Job实现类package com.baobaotao.basic.quartz;import java.util.Date;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;public class SimpleJob implements Job {①实例Job接口方法public void execute(JobExecutionContext jobCtx)throws JobExecutionException {System.out.println(jobCtx.getTrigger().getName()+ " triggered. time is:" + (new Date()));}}这个类用一条非常简单的输出语句实现了Job接口的execute(JobExecutionContext context) 方法,这个方法可以包含想要执行的任何代码。