1.   pom.xml

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

2.  quartz.properties

#============================================================================
# Configure Main Scheduler Properties 集群的配置
#============================================================================
org.quartz.scheduler.instanceName = DefaultQuartzScheduler
org.quartz.scheduler.instanceId = AUTO
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.wrapJobExecutionInUserTransaction = false
#============================================================================
# Configure ThreadPool 配置调度器的线程池
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 30
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
#============================================================================
# Configure JobStore 配置任务调度现场数据保存机制
#============================================================================
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
#org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 15000
#============================================================================
# Configure DataSource
#============================================================================
#org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
#org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost/test
#org.quartz.dataSource.myDS.user = root
#org.quartz.dataSource.myDS.password = root
#org.quartz.dataSource.myDS.maxConnections = 10

3.   applicationContext.xml

    <!-- 固定job数和时间 -->
<bean id="strapJob" class="cn.xue.Scheduler.service.MyJob2">
<property name="targetBeanName" value="dataItemManager" />
<property name="targetBeanMethod" value="add" />
<property name="targetBeanArguments" value="王" />
</bean>
<bean  id ="compareJob"  class ="cn.xue.Scheduler.service.MyMethodInvokingBean" >
<property name="concurrent" value="true" />
<property name="targetObject" ref="strapJob" />
<property name="targetMethod" value="execute" />
</bean>
<bean  id ="compareTrigger"  class ="org.springframework.scheduling.quartz.CronTriggerBean" >
<property  name ="jobDetail"  ref ="compareJob"   />
<property  name ="cronExpression" >
<value>0 0/1 * * * ?</value>
</property >
</bean>
<!-- 不定job数和时间 -->
<bean  id="schedulerManager" class="cn.xue.Scheduler.service.SchedulerManager"/>
<bean name="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false">
<property name="dataSource" ref="dataSource"/>
<property  name ="triggers">
<list>
<ref  local ="compareTrigger"/>
</list>
</property>
<property name="configLocation" value="classpath:quartz.properties"/>
<property name="startupDelay" value="1"></property>
<property name="overwriteExistingJobs" value="true"/>
<property name="schedulerContextAsMap">
<map>
<description>schedulerContextAsMap</description>
<entry key="loopbkmkTreeDao" value-ref="loopbkmkTreeDao"/>
</map>
</property>
<property name="applicationContextSchedulerContextKey">
<value>applicationContext</value>
</property>
</bean>

4.   MyJob2

package cn.xue.Scheduler.service;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.springframework.context.ApplicationContext;

public class MyJob2 implements Serializable{
 
 public void execute(ApplicationContext ctx) {
  try {
   Object dm = ctx.getBean(this.targetBeanName);
   Method method = dm.getClass().getMethod(targetBeanMethod,String.class);
   method.invoke(dm, targetBeanArguments);
  } catch (SecurityException e) {
   e.printStackTrace();
  } catch (NoSuchMethodException e) {
   e.printStackTrace();
  } catch (IllegalArgumentException e) {
   e.printStackTrace();
  } catch (IllegalAccessException e) {
   e.printStackTrace();
  } catch (InvocationTargetException e) {
   e.printStackTrace();
  }
 }
 private String targetBeanArguments ;
 private String targetBeanName ;
 private String targetBeanMethod ;
 
 public String getTargetBeanName() {
  return targetBeanName;
 }
 public void setTargetBeanName(String targetBeanName) {
  this.targetBeanName = targetBeanName;
 }
 public String getTargetBeanMethod() {
  return targetBeanMethod;
 }
 public void setTargetBeanMethod(String targetBeanMethod) {
  this.targetBeanMethod = targetBeanMethod;
 }
 public String getTargetBeanArguments() {
  return targetBeanArguments;
 }
 public void setTargetBeanArguments(String targetBeanArguments) {
  this.targetBeanArguments = targetBeanArguments;
 }
}

/*
●Job:是一个接口,只有一个方法void execute(JobExecutionContext context),开发者实现该接口定义运行任务,
 JobExecutionContext类提供了调度上下文的各种信息。Job运行时的信息保存在JobDataMap实例中;
●JobDetail:Quartz在每次执行Job时,都重新创建一个Job实例,所以它不直接接受一个Job的实例,相反它接收一个Job实现类,
 以便运行时通过newInstance()的反射机制实例化Job。因此需要通过一个类来描述Job的实现类及其它相关的静态信息,如Job名字、描述、关联监听器等信息,JobDetail承担了这一角色。
 通过该类的构造函数可以更具体地了解它的功用:JobDetail(java.lang.String name, java.lang.String group, java.lang.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实例;
●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拥有完善的事件和监听体系,大部分组件都拥有事件,如任务执行前事件、任务执行后事件、触发器触发前事件、触发后事件、调度器开始事件、关闭事件等等,可以注册相应的监听器处理感兴趣的事件。

一个Scheduler可以拥有多个Triger组和多个JobDetail组,注册Trigger和JobDetail时,如果不显式指定所属的组,Scheduler将放入到默认组中,默认组的组名为Scheduler.DEFAULT_GROUP。
组名和名称组成了对象的全名,同一类型对象的全名不能相同。Scheduler本身就是一个容器,它维护着Quartz的各种组件并实施调度的规则。Scheduler还拥有一个线程池,线程池为任务提供执行线程——
这比执行任务时简单地创建一个新线程要拥有更高的效率,同时通过共享节约资源的占用。通过线程池组件的支持,对于繁忙度高、压力大的任务调度,Quartz将可以提供良好的伸缩性。

任务调度信息存储

在默认情况下Quartz将任务调度的运行信息保存在内存中,这种方法提供了最佳的性能,因为内存中数据访问最快。不足之处是缺乏数据的持久性,当程序路途停止或系统崩溃时,所有运行的信息都会丢失。
如果确实需要持久化任务调度信息,Quartz允许你通过调整其属性文件,将这些信息保存到数据库中。使用数据库保存任务调度信息后,即使系统崩溃后重新启动,任务的调度信息将得到恢复。

QRTZ_BLOG_TRIGGERS Trigger 作为 Blob 类型存储(用于 Quartz 用户用 JDBC 创建他们自己定制的 Trigger 类型,JobStore 并不知道如何存储实例的时候)
QRTZ_CALENDARS 以 Blob 类型存储 Quartz 的 Calendar 信息
QRTZ_CRON_TRIGGERS 存储 Cron Trigger,包括 Cron 表达式和时区信息
QRTZ_FIRED_TRIGGERS 存储与已触发的 Trigger 相关的状态信息,以及相联 Job 的执行信息
QRTZ_JOB_DETAILS 存储每一个已配置的 Job 的详细信息
QRTZ_JOB_LISTENERS 存储有关已配置的 JobListener 的信息
QRTZ_LOCKS 存储程序的非观锁的信息(假如使用了悲观锁)
QRTZ_PAUSED_TRIGGER_GRPS 存储已暂停的 Trigger 组的信息
QRTZ_SCHEDULER_STATE 存储少量的有关 Scheduler 的状态信息,和别的 Scheduler 实例(假如是用于一个集群中)
QRTZ_SIMPLE_TRIGGERS 存储简单的 Trigger,包括重复次数,间隔,以及已触的次数
QRTZ_TRIGGERS 存储已配置的 Trigger 的信息
QRTZ_TRIGGER_LISTENERS 存储已配置的 TriggerListener 的信息

org.quartz.scheduler.instanceName属性可为任何值,用在 JDBC JobStore 中来唯一标识实例,但是所有集群节点中必须相同。
org.quartz.scheduler.instanceId 属性为 AUTO即可,基于主机名和时间戳来产生实例 ID。
org.quartz.jobStore.class属性为 JobStoreTX,将任务持久化到数据中。因为集群中节点依赖于数据库来传播 Scheduler 实例的状态,
 你只能在使用 JDBC JobStore 时应用 Quartz 集群。这意味着你必须使用 JobStoreTX 或是 JobStoreCMT 作为 Job 存储;你不能在集群中使用 RAMJobStore。
org.quartz.jobStore.isClustered 属性为 true,你就告诉了 Scheduler 实例要它参与到一个集群当中。这一属性会贯穿于调度框架的始终,用于修改集群环境中操作的默认行为。
org.quartz.jobStore.clusterCheckinInterval 属性定义了Scheduler 实例检入到数据库中的频率(单位:毫秒)。Scheduler 检查是否其他的实例到了它们应当检入的时候未检入;
 这能指出一个失败的 Scheduler 实例,且当前 Scheduler 会以此来接管任何执行失败并可恢复的 Job。通过检入操作,Scheduler 也会更新自身的状态记录。
 clusterChedkinInterval 越小,Scheduler 节点检查失败的 Scheduler 实例就越频繁。默认值是 15000 (即15 秒)。
org.quartz.jobStore.useProperties这个属性能够设置为“true”(默认为false),用来指示JDBCJobStore:在JobDataMaps里的所有值都应该是String,这样在能作为name-value方式储存,
 而不是在BLOB列里以序列化的格式储存复杂的对象。从长远看,这样做会很安全,因为你可以避免将非String的类序列化到BLOB里的类版本问题。
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
 需要选择一个驱动代理。StdJDBCDelegate是一个用“vanilla”JDBC代码实现的代理。如果没有其他为你数据库指定的代理,就使用这个。
 Quartz开发者们解决的问题都是根据这个代理的来实现的。其他的代理在org.quartz.impl.jdbcjobstore包或者子包里。包括DB2v6Delegate(DB2 version 6 或早期版本使用的),
 HSQLDBDelegate(HSQLDB使用),MSSQLDelegate(microsoft SQLServer 2000使用),PostgreSQLDelegate(PostgreSQL 7.x使用),WeblogicDelegate(Weblogic的JDBC驱动器使用),
 OracleDelegate(Oracle 8i and 9i使用)。

applicationContextSchedulerContextKey: 是org.springframework.scheduling.quartz.SchedulerFactoryBean这个类中把spring上下 文以key/value的方式存放在了quartz的上下文中了,
 可以用applicationContextSchedulerContextKey所 定义的key得到对应的spring上下文;

Quartz 实际并不关心你是在相同的还是不同的机器上运行节点。当集群是放置在不同的机器上时,通常称之为水平集群。节点是跑在同一台机器是,称之为垂直集群。
 对于垂直集群,存在着单点故障的问题。这对高可用性的应用来说是个坏消息,因为一旦机器崩溃了,所有的节点也就被有效的终止了。
 当你运行水平集群时,时钟应当要同步,以免出现离奇且不可预知的行为。假如时钟没能够同步,Scheduler 实例将对其他节点的状态产生混乱。有几种简单的方法来保证时钟何持同步,
 而且也没有理由不这么做。最简单的同步计算机时钟的方式是使用某一个 Internet 时间服务器(Internet Time Server ITS)。

SimpleTrigger -----   org.quartz.TriggerUtils工具类

*/

quartz的使用(一)相关推荐

  1. SpringBoot中实现quartz定时任务

    Quartz整合到SpringBoot(持久化到数据库) 背景 最近完成了一个小的后台管理系统的权限部分,想着要扩充点东西,并且刚好就完成了一个自动疫情填报系统,但是使用的定时任务是静态的,非常不利于 ...

  2. Java基于Quartz的定时任务调度服务(一)

    Quartz的基本用法 一 Quartz的简单介绍 Quartz 是 OpenSymphony 开源组织在任务调度领域的一个开源项目,完全基于 Java 实现,一个优秀的开源调度框架,其特点是:强大的 ...

  3. springboot整合Quartz实现动态配置定时任务

    版权声明:本文为博主原创文章,转载请注明出处. https://blog.csdn.net/liuchuanhong1/article/details/60873295 前言 在我们日常的开发中,很多 ...

  4. Quartz 2D Programming Guide笔记

    ###Graphics Contexts图形上下文### 图形上下文(graphics context)是绘制目标,可以理解为画布,包含着绘图时的参数和设备信息.类型为CGContextRef.获取g ...

  5. 【Quartz】实现接口封装化(二)

    原文:[Quartz]实现接口封装化(二)   前言   通过昨天的努力终于算是了解Quartz这个定时器的简单使用,为了更深一步的了解和基于以后希望在项目中能使用他.所有我对他做了一下简单的封装操作 ...

  6. quartz在集群环境下的最终解决方案

    在集群环境下,大家会碰到一直困扰的问题,即多个 APP 下如何用 quartz 协调处理自动化 JOB . 大家想象一下,现在有 A , B , C3 台机器同时作为集群服务器对外统一提供 SERVI ...

  7. 将Quartz.NET集成到 Castle中

    Castle是针对.NET平台的一个开源项目,从数据访问框架ORM到IOC容器,再到WEB层的MVC框架.AOP,基本包括了整个开发过程中的所有东西,为我们快速的构建企业级的应用程序提供了很好的服务. ...

  8. 初识Quartz(三)

    为什么80%的码农都做不了架构师?>>>    简单作业: package quartz_project.example3;import java.util.Date;import ...

  9. java timer cron_Java之旅--定时任务(Timer、Quartz、Spring、LinuxCron)

    在Java中,实现定时任务有多种方式.本文介绍4种.Timer和TimerTask.Spring.QuartZ.Linux Cron. 以上4种实现定时任务的方式.Timer是最简单的.不须要不论什么 ...

  10. Quartz动态添加、修改和删除定时任务

    2019独角兽企业重金招聘Python工程师标准>>> Quartz动态添加.修改和删除定时任务 转载于:https://my.oschina.net/haokevin/blog/1 ...

最新文章

  1. 字符串匹配算法 -- BM(Boyer-Moore) 和 KMP(Knuth-Morris-Pratt)详细设计及实现
  2. 马云启动“NASA”计划 为未来20年愿景研发核心科技
  3. Android之如何成为Android高手
  4. rsync 同步优化_可以优化同步吗?
  5. java生成unix.z压缩_JAVA压缩 解压缩zip 并解决linux下中文乱码
  6. “Emgu.CV.CvInvoke”的类型初始值设定项引发异常 解决办法
  7. stm32中断 抢占优先级 和 响应优先级 有什么区别
  8. LINUX获取当前用户及信息的命令
  9. 杀软自己做 编写autorun病毒免疫工具
  10. SimNow仿真交易【官方环境介绍】 期货仿真环境地址 期货模拟交易
  11. java 避免gc_减少JAVA GC
  12. 招银网络科技校园招聘面试2020.10
  13. 游戏运营的工作中是做什么
  14. 动态博弈--gyy参考总结
  15. 投资是一个非常专业的领域,亏钱容易赚钱难
  16. 报销差率费与会计借贷理解
  17. BuuCTF_crypto(2021.10.8新-->旧)
  18. Unity-Live2d(鼠标拖拽触发动作变化)
  19. 软件------关于spacedesk分屏软件的使用说明(包括下载和具体启动方式)
  20. NC65开发使用UAP-STUDIO6.5发布WebService

热门文章

  1. 事务四大特性(ACID)原子性、一致性、隔离性、持久性
  2. HPC应用软件安装《hmmer》
  3. AutoResetEvent与ManualResetEvent区别
  4. ManualResetEvent,AutoResetEvent 学习
  5. 计算机毕业设计Java企业人事管理系统(源码+系统+mysql数据库+lw文档)
  6. JAVA实现Doc与Docx互转
  7. 浅谈神经网络之链式法则与反向传播算法
  8. Freetype学习笔记
  9. python网络爬虫一
  10. 计算机ab级ppt,计算机二级MS_Office考试PPT题型汇总附答案