转载

【Quartz指南】配置文件里配置项总结

设置主要调度器

属性名 必须 类型 缺省值
org.quartz.scheduler.instanceName no string 'QuartzScheduler'
org.quartz.scheduler.instanceId no string 'NON_CLUSTERED'
org.quartz.scheduler.threadName no string instanceName + '_QuartzSchedulerThread'
org.quartz.scheduler.idleWaitTime no long 30000
org.quartz.scheduler.dbFailureRetryInterval no long 15000
org.quartz.scheduler.classLoadHelper.class no string (class name) org.quartz.simpl.CascadingClassLoadHelper
org.quartz.context.key.SOME_KEY no string none
org.quartz.scheduler.userTransactionURL no string (url) 'java:comp/UserTransaction'
org.quartz.scheduler.wrapJobExecutionInUserTransaction no booelan false
org.quartz.scheduler.jobFactory.class no string (class name) org.quartz.simpl.SimpleJobFactory
org.quartz.scheduler.instanceName 任意的String,对于调度器自己并没有意义。但是当多个调度器实例用在一个程序里时,他就可以用来为客户端代码区别每个调度器。如果你用集群这个特性,你必须为在集群里的每个实例用一样的名字,实现逻辑上的一样的调度器。 org.quartz.scheduler.instanceId 任意的String,如果在一个集群里多个实例是一个逻辑上一样的调度器时,每个实例的这项属性必须唯一。你可以设置这项为“AUTO”从而自动收集ID。 org.quartz.scheduler.idleWaitTime 当调度器空闲时,在再次查询可用triggers之前,调度器将要等等待的毫秒数。正常情况下,我们不调整这个参数,除非我们用XA事务,或者在立即触发trigger时结果延误了。 org.quartz.scheduler.classLoadHelper.class 不需要更改。 org.quartz.context.key.SOME_KEY 设置org.quartz.context.key.MyKey = MyValue等价于scheduler.getContext().put("MyKey", "MyValue") org.quartz.scheduler.userTransactionURL 是一个JNDI URL,Quartz用它来定位应用服务器的UserTransaction管理器。Websphere用户可能需要设置它为“jta/usertransaction”。在Quartz配置用到JobStoreCMT时并且属性org.quartz.scheduler.wrapJobExecutionInUserTransaction设置为true才有用 org.quartz.scheduler.wrapJobExecutionInUserTransaction 设置这项为true使我们在调用job的execute()之前能够开始一个UserTransaction。在job的execute()完成之后,事务将会提交,并且,JobDataMap也更新了(是有状态的job)。

设置线程池

属性名 必须 类型 缺省值
org.quartz.threadPool.class yes string (clas name) null
org.quartz.threadPool.threadCount yes int -1
org.quartz.threadPool.threadPriority no int Thread.NORM_PRIORITY (5)
org.quartz.threadPool.makeThreadsDaemons no boolean false
org.quartz.threadPool.threadsInheritGroupOfInitializingThread no boolean true
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread no boolean false
org.quartz.threadPool.class 通常使用org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadPriorityThread.MIN_PRIORITY (1) 和Thread.MAX_PRIORITY (10)之间 org.quartz.threadPool.makeThreadsDaemonsorg.quartz.threadPool.threadsInheritGroupOfInitializingThread org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread 三个属性是指定的SimpleThreadPool的属性。 如果用自己实现的线程池,可如下配置: org.quartz.threadPool.class = com.mycompany.goo.FooThreadPool org.quartz.threadPool.somePropOfFooThreadPool = someValue

设置全局监听器

全局监听器要有一个无参数的构造器,它的属性是通过反射设置的,仅支持简单数据和String。
Trigger监听器: org.quartz.triggerListener.NAME.class = com.foo.MyListenerClass org.quartz.triggerListener.NAME.propName = propValue org.quartz.triggerListener.NAME.prop2Name = prop2Value job监听器: org.quartz.jobListener.NAME.class = com.foo.MyListenerClass org.quartz.jobListener.NAME.propName = propValue org.quartz.jobListener.NAME.prop2Name = prop2Value

设置Plugins

配置自己的插件(和全局监听器差不多): org.quartz.plugin.NAME.class = com.foo.MyPluginClass org.quartz.plugin.NAME.propName = propValue org.quartz.plugin.NAME.prop2Name = prop2Value 也可以配置Quartz实现的插件: 1.trigger历史日志记录插件(属性配置中的{数字}参考JavaDoc): org.quartz.plugin.triggHistory.class=org.quartz.plugins.history.LoggingTriggerHistoryPlugin org.quartz.plugin.triggHistory.triggerFiredMessage= Trigger {1}.{0} fired job {6}.{5} at:{4, date, HH:mm:ss MM/dd/yyyy} org.quartz.plugin.triggHistory.triggerCompleteMessage = Trigger {1}.{0} completed firing job {6}.{5} at {4, date, HH:mm:ss MM/dd/yyyy} 2.从XML文件中初始化job的插件(属性配置中的文件名是加载jobs用到的xml文件,这个文件必须在classPath里): org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.JobInitializationPlugin org.quartz.plugin.jobInitializer.fileName =data/my_job_data.xml org.quartz.plugin.jobInitializer.overWriteExistingJobs = false org.quartz.plugin.jobInitializer.failOnFileNotFound = true 在上例中,JobInitializationPlugin只支持一个xml文件的初始化,Quartz还提供多个xml文件的初始化,用JobInitializationPluginMultiple,文件名用“,”隔开。 含有多个Jobs的一个xml文件的一个例子: <?xml version='1.0' encoding='utf-8'?> <quartz xmlns="http://www.opensymphony.com/quartz/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opensymphony.com/quartz/JobSchedulingData http://www.opensymphony.com/quartz/xml/job_scheduling_data_1_5.xsd" version="1.5">   <calendar class-name="org.quartz.impl.calendar.HolidayCalendar" replace="true"> <name>holidayCalendar</name> <description>HolidayCalendar</description> <base-calendar class-name="org.quartz.impl.calendar.WeeklyCalendar"> <name>weeklyCalendar</name> <description>WeeklyCalendar</description> <base-calendar class-name="org.quartz.impl.calendar.AnnualCalendar"> <name>annualCalendar</name> <description>AnnualCalendar</description> </base-calendar> </base-calendar> </calendar>   <job> <job-detail> <name>testJob1</name> <group>testJobs</group> <description>Test Job Number 1</description> <job-class>personal.ruanyang.quartz.plugin.SimpleJob</job-class> <volatility>false</volatility> <durability>false</durability> <recover>false</recover> <job-data-map allows-transient-data="true"> <entry> <key>test1</key> <value>test1</value> </entry> <entry> <key>test2</key> <value>test2</value> </entry> </job-data-map> </job-detail> <trigger> <cron> <name>testTrigger1</name> <group>testJobs</group> <description>Test Trigger Number 1</description> <job-name>testJob1</job-name> <job-group>testJobs</job-group>   <!-- <start-time>2003-12-17 2:15:00 pm</start-time> <end-time>2013-12-17 2:15:00 pm</end-time> -->   <cron-expression>0/15 * * ? * *</cron-expression> <!-- every 15 seconds... --> </cron> </trigger> </job>   <job> <job-detail> <name>testJob2</name> <group>testJobs</group> <description>Test Job Number 2</description> <job-class>personal.ruanyang.quartz.plugin.SimpleJob</job-class> <volatility>false</volatility> <durability>false</durability> <recover>false</recover> </job-detail> <trigger> <simple> <name>testTrigger2</name> <group>testJobs</group> <description>Test Trigger Number 2</description> <calendar-name>holidayCalendar</calendar-name> <job-name>testJob2</job-name> <job-group>testJobs</job-group> <start-time>2004-02-26T12:26:00</start-time> <repeat-count>10</repeat-count> <repeat-interval>5000</repeat-interval> </simple> </trigger> </job>   </quartz>   3.Shutdown Hook(通过捕捉JVM关闭时的事件,来关闭调度器)插件: org.quartz.plugin.shutdownhook.class = org.quartz.plugins.management.ShutdownHookPlugin org.quartz.plugin.shutdownhook.cleanShutdown = true

设置RMI

RMI Server Scheduler Properties 没有必需的主要属性,所有的都是合理的缺省的。通过RMI使用Quartz时,我们需要启动一个配置好了的Quartz实例来通过RMI“输出”它的服务。然后我们通过配置Quartz的调度器创建一个客户端来“代理”它连到服务器上的工作。 一些用户在客户端和服务器端经历过类可用性(jobs classes)的问题,为了解决这些问题,我们需要理解RMI的“codebase”和RMI的安全管理。以下资源在这方面会很有用: RMI和codebase的精彩描叙:http://www.kedwards.com/jini/codebase.html  重要的一点要意识到,codebase是被客户端使用的。 安全管理的快速信息:http://gethelp.devx.com/techtips/java_pro/10MinuteSolutions/10min0500.asp 最后读来自于java API文档的RMISecurityManager: http://java.sun.com/j2se/1.4.2/docs/api/java/rmi/RMISecurityManager.html
属性名 需要 缺省值
org.quartz.scheduler.rmi.export no false
org.quartz.scheduler.rmi.registryHost no 'localhost'
org.quartz.scheduler.rmi.registryPort no 1099
org.quartz.scheduler.rmi.createRegistry no 'never'
org.quartz.scheduler.rmi.serverPort no random
org.quartz.scheduler.rmi.proxy no false
org.quartz.scheduler.rmi.export 如果我们想要Quartz调度器通过RMI输出服务,那么我们就把“rmi.export”标志执为true。 org.quartz.scheduler.rmi.registryHost 能够找到的RMI注册的主机(常为“localhost”)。 org.quartz.scheduler.rmi.registryPort RMI注册的监听端口(常为1099). org.quartz.scheduler.rmi.createRegistry 设置“rmi.createRegistry” 依照我们想要Quartz怎样创建RMI注册。如果我们不想Quartz创建一个注册,就可以用“false”或“never”(如已经有了一个外部的注册在运行了)。如果我们想先要Quartz尝试使用一个存在的注册并且然后返回再建一个,就用“true”或者“as_needed”。如果我们想要Quartz尝试创建一个注册然后返回使用一个存在的,就用“always”。如果注册被创建,它将会绑定属性“org.quartz.scheduler.rmi.registryPort”提供的端口,“org.quartz.rmi.registryHost”应该是主机。 org.quartz.scheduler.rmi.serverPort Quartz调度器服务将绑定和监听连接的端口。缺省的,RMI服务将随机选择一个端口。 org.quartz.scheduler.rmi.proxy 如果想要连接到远程的调度器服务,我们就要设置“org.quartz.scheduler.rmi.proxy”为true。然后必需指定一个主机和它注册了的端口号。 在同一个文件里给“org.quartz.scheduler.rmi.export”和“org.quartz.scheduler.rmi.proxy”同时设置为true并没有意义。如果你这样做的话,“export”项会被忽略。如果你没有通过RMI用Quartz,给这两项同时设置为false当然也没有用。

设置RAMJobStore

RAMJobStore用来在内存里储存调度时的信息(job,trigger,calendars)。RAMJobStore很快并且是轻量级的,但是当进程终止时所有的信息都将丢失。 通过设置“org.quartz.jobStore.class”属性来选用RAMJobStore org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore RAMJobStore 能够通过下面的属性来调整:
属性名 需要 类型 缺省值
org.quartz.jobStore.misfireThreshold no int 60000
org.quartz.jobStore.misfireThreshold 在触发器被认为没有触发之前,调度器能承受一个触发器再次触发的一个毫秒级数字。

设置JDBC-JobStoreTX

JobStoreTX是在每次行为(如增加一个job)之后,通过调用commit() (或者 rollback())来管理事务。如果你在一个单机应用里或者当在一个servlet容器里用Quartz而且应用没有用JTA事务时,JDBCJobStore是正确的。 JobStoreTX是通过设置“org.quartz.jobStore.class”属性来选用的: org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX JobStoreTX能够通过以下属性来调整:
属性名 必须 类型 缺省值
org.quartz.jobStore.driverDelegateClass yes string null
org.quartz.jobStore.dataSource yes string null
org.quartz.jobStore.tablePrefix no string "QRTZ_"
org.quartz.jobStore.useProperties no boolean false
org.quartz.jobStore.misfireThreshold no int 60000
org.quartz.jobStore.isClustered no boolean false
org.quartz.jobStore.clusterCheckinInterval no long 15000
org.quartz.jobStore.maxMisfiresToHandleAtATime no int 20
org.quartz.jobStore.dontSetAutoCommitFalse no boolean false
org.quartz.jobStore.selectWithLockSQL no string "SELECT * FROM {0}LOCKS WHERE LOCK_NAME = ? FOR UPDATE"
org.quartz.jobStore.txIsolationLevelSerializable no boolean false
org.quartz.jobStore.driverDelegateClass
  • org.quartz.impl.jdbcjobstore.StdJDBCDelegate (所有JDBC兼容的驱动)
  • org.quartz.impl.jdbcjobstore.MSSQLDelegate (Microsoft SQL Server和Sybase)
  • org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
  • org.quartz.impl.jdbcjobstore.WebLogicDelegate (WebLogic驱动)
  • org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
  • org.quartz.impl.jdbcjobstore.oracle.WebLogicOracleDelegate (用在Weblogic里的Oracle驱动)
  • org.quartz.impl.jdbcjobstore.oracle.weblogic.WebLogicOracleDelegate (用在Weblogic里的Oracle驱动)
  • org.quartz.impl.jdbcjobstore.CloudscapeDelegate
  • org.quartz.impl.jdbcjobstore.DB2v6Delegate
  • org.quartz.impl.jdbcjobstore.DB2v7Delegate
  • org.quartz.impl.jdbcjobstore.HSQLDBDelegate
  • org.quartz.impl.jdbcjobstore.PointbaseDelegate
org.quartz.jobStore.misfireThreshold 同RAM org.quartz.jobStore.clusterCheckinInterval 影响着核查出失败实例的速度。 org.quartz.jobStore.dontSetAutoCommitFalse 设置这个属性为“true”是让Quartz不去在JDBC连接上调用setAutoCommit(false)这个函数。 org.quartz.jobStore.selectWithLockSQL 在“LOCKS”表里选择一行并且锁住这行的SQL语句。缺省的语句能够为大部分数据库工作。“{0}”是在运行时你配置的表前缀。 org.quartz.jobStore.txIsolationLevelSerializable 设置“true”让Quartz(当用JobStoreTX或CMT)在JDBC连接上调用setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE)。这可以阻止数据库在高加载或长时间的事务情况下的锁超时。

设置JDBC-JobStoreCMT

JobStoreCMT是依赖与被用Quartz的应用管理着的事务。JTA事务必须在尝试调度(或卸载调度)jobs/triggers之前处在进程中。这允许调度工作成为应用加大事务的一部分。JobStoreCMT实际上需要用到两个数据源,一个数据源要连到被应用服务器管理的事务(通过JTA),另外一个数据源的连接在全局(JTA)事务中并不参加。当应用用JTA事务(例如通过EJB Session Beans)来执行他们的工作时,JobStoreCMT是正确的。 通过设置 'org.quartz.jobStore.class'属性来选用JobStore: org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreCMT JobStoreCMT通过以下属性来调整:
属性名 必须 类型 缺省值
org.quartz.jobStore.driverDelegateClass yes string null
org.quartz.jobStore.dataSource yes string null
org.quartz.jobStore.nonManagedTXDataSource yes string null
org.quartz.jobStore.tablePrefix no string "QRTZ_"
org.quartz.jobStore.useProperties no boolean false
org.quartz.jobStore.misfireThreshold no int 60000
org.quartz.jobStore.isClustered no boolean false
org.quartz.jobStore.clusterCheckinInterval no long 15000
org.quartz.jobStore.maxMisfiresToHandleAtATime no int 20
org.quartz.jobStore.dontSetAutoCommitFalse no boolean false
org.quartz.jobStore.dontSetNonManagedTXConnectionAutoCommitFalse no boolean false
org.quartz.jobStore.selectWithLockSQL no string "SELECT * FROM {0}LOCKS WHERE LOCK_NAME = ? FOR UPDATE"
org.quartz.jobStore.txIsolationLevelSerializable no boolean false
org.quartz.jobStore.txIsolationLevelReadCommitted no boolean false
org.quartz.jobStore.dataSource 对于JobStoreCMT,数据源需要包含能够加入JTA(容器管理)事务里的连接。这就意味着数据源将在应用服务器里被配置和管理,并且,Quartz将通过JNDI获得一个句柄。 org.quartz.jobStore.nonManagedTXDataSource JobStoreCMT需要一个数据源(以上说的第二个)连到不是容器管理的事务。这个值将是定义在配置属性文件的一个数据源名称,这个数据源必须包含非CMT的连接,换句话说,就是Quartz直接在连接上调用commit()和rollback()。 org.quartz.jobStore.dontSetNonManagedTXConnectionAutoCommitFalse 除了它应用于非TX数据源管理,其他的和org.quartz.jobStore.dontSetAutoCommitFalse一样 org.quartz.jobStore.txIsolationLevelReadCommitted 设置“true”,让Quartz在没有被管理的JDBC连接上调用setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED)。这可以阻止一些数据库(如DB2)在高加载和长时间事务的情况下发生的锁超时。

设置数据源

如果你用JDBC-JobStore,你将需要一个数据源(或在JobStoreCMT里要2个)。 数据源能通过2种方法配置:
  1. Quartz搜集所有指定在quartz.properties 文件里的属性来创建数据源。
  2. 指定一个定位于管理数据源的应用服务器的JNDI,这样Quartz能用它。
每个定义的数据源必须有个名字,你为这个数据源定义的一些属性必须包含这个名字,象下面的。数据源的“NAME”可以随便取,只有当我们把数据源赋给JDBCJobStore时,这个名字起到标示的作用,其他情况下没什么用。 Quartz自己创建数据源通过以下属性:
属性名 必须 类型 缺省值
org.quartz.dataSource.NAME.driver yes String null
org.quartz.dataSource.NAME.URL yes String null
org.quartz.dataSource.NAME.user no String ""
org.quartz.dataSource.NAME.password no String ""
org.quartz.dataSource.NAME.maxConnections no int 10
org.quartz.dataSource.NAME.validationQuery no String null
org.quartz.dataSource.NAME.validationQuery 是一个可选的SQL查询字符串,数据源用它来核查和替代失败/被破坏的连接。例如,一个Oracle用户可能选择“select table_name from user_tables”-这是一个决不可能失败的查询,除非连接是坏的。
org.quartz.dataSource.myDS.driver = oracle.jdbc.driver.OracleDriver org.quartz.dataSource.myDS.URL = jdbc:oracle:thin:@10.0.1.23:1521:demodb org.quartz.dataSource.myDS.user = myUser org.quartz.dataSource.myDS.password = myPassword org.quartz.dataSource.myDS.maxConnections = 30
引用应用服务器的数据源:
属性值 必须 类型 缺省值
org.quartz.dataSource.NAME.jndiURL yes String null
org.quartz.dataSource.NAME.java.naming.factory.initial no String null
org.quartz.dataSource.NAME.java.naming.provider.url no String null
org.quartz.dataSource.NAME.java.naming.security.principal no String null
org.quartz.dataSource.NAME.java.naming.security.credentials no String null
org.quartz.dataSource.NAME.java.naming.factory.initial JNDI上下文初始化工厂的类名。 org.quartz.dataSource.NAME.java.naming.provider.url 连接到JNDI上下文的URL。 org.quartz.dataSource.NAME.java.naming.security.principal 连接到JNDI上下文的首要用户。 org.quartz.dataSource.NAME.java.naming.security.credentials 连接到JNDI上下文的用户验证密码。
org.quartz.dataSource.myOtherDS.jndiURL=jdbc/myDataSource org.quartz.dataSource.myOtherDS.java.naming.factory.initial= com.evermind.server.rmi.RMIInitialContextFactory org.quartz.dataSource.myOtherDS.java.naming.provider.url=ormi://localhost org.quartz.dataSource.myOtherDS.java.naming.security.principal=admin org.quartz.dataSource.myOtherDS.java.naming.security.credentials=123

设置集群

集群可以通过fail-over和load balancing功能给调度器带来既高可靠性又可伸缩性两大优点。 集群目前仅能和JDBC-JobStore(JobStoreTX或JobStoreCMT)一起工作,本质上是让集群的每个节点共享一个数据库来工作的。 Load-balancing是自动出现的,集群的每个节点尽可能快地触发job。当一个触发器触发时刻到了,第一个将获取触发器(并加锁)的节点就是将要触发它的节点。 Fail-over是一个节点正在执行一个或多个jobs时失败了出现的。当一个节点失败了,其他的节点就会在数据库里核查条件和鉴别jobs,这些是节点失败时记录到了数据库的。在恢复节点时,任何标记了恢复(JobDetail里的"requests recovery"属性)的jobs将会被再次执行,没有标记的将会简单地释放掉。 通过设置“org.quartz.jobStore.isClustered”属性来使用集群。在集群里每个实例应该用一样的quartz.properties文件。用到的异常也应该是一样的:不同线程池大小,不同“org.quartz.scheduler.instanceName”属性值。每个节点应该用唯一的instanceId。我们可以设置org.quartz.scheduler.instanceId的值为“AUTO”来达到这个目的。 不要在一个分离开的机器上运行集群,除非他们的时钟是用时钟同步服务同步过的。如果不熟悉怎样同步,参考:http://www.boulder.nist.gov/timefreq/service/its.htm 其他实例在用数据表时,不要触发一个不是集群的也用这些数据表的实例。你会得到一些没用的数据。 #=================================================================# Configure Main Scheduler Properties #=================================================================org.quartz.scheduler.instanceName = MyClusteredScheduler org.quartz.scheduler.instanceId = AUTO #=================================================================# Configure ThreadPool #================================================================= org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount = 25 org.quartz.threadPool.threadPriority = 5 #=================================================================# 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.useProperties = false org.quartz.jobStore.dataSource = myDS org.quartz.jobStore.tablePrefix = QRTZ_ org.quartz.jobStore.isClustered = true org.quartz.jobStore.clusterCheckinInterval = 20000 #================================================================= # Configure Datasources #================================================================= org.quartz.dataSource.myDS.driver = oracle.jdbc.driver.OracleDriver org.quartz.dataSource.myDS.URL = jdbc:oracle:thin:@polarbear:1521:dev org.quartz.dataSource.myDS.user = quartz org.quartz.dataSource.myDS.password = quartz org.quartz.dataSource.myDS.maxConnections = 5 org.quartz.dataSource.myDS.validationQuery=select 0 from dual

14.在Web应用中用Quartz

初始化调度器

我们可以在Web应用中的配置文件web.xml里设置一个Quartz的Servlet-QuartzInitializerServlet:
<web-app>   <servlet> <servlet-name>QuartzInitializer</servlet-name>  <display-name>Quartz Initializer Servlet</display-name><servlet-class>   org.quartz.ee.servlet.QuartzInitializerServlet </servlet-class>   <load-on-startup>1</load-on-startup>  <init-param>   <param-name>config-file</param-name>   <param-value>/some/path/my_quartz.properties</param-value> </init-param>  <init-param>   <param-name>shutdown-on-unload</param-name>   <param-value>true</param-value> </init-param>  <init-param>   <param-name>start-scheduler-on-load</param-name>   <param-value>true</param-value> </init-param>  </servlet>   <!-- other web.xml items here --> </web-app>
说明:config-file参数值是StdSchedulerFactory用来实例化调度器的,可以把自己写的Quartz属性文件放在classPath即WEB-INF/classes路径下。

访问调度器

从Quartz1.5开始,QuartzInitializerServlet将自动储存StdSchedulerFactory实例在ServletContext里: // 从Session中获得ServletContext
              ServletContext ctx = request.getSession().getServletContext(); // 从ServletContext中获得StdSchedulerFactory StdSchedulerFactory factory = (StdSchedulerFactory)ctx.getAttribute( QuartzFactoryServlet.QUARTZ_FACTORY_KEY); // 从StdSchedulerFactory中获得Scheduler Scheduler scheduler = factory.getScheduler(); // 启动Scheduler scheduler.start();
正文到此结束
Loading...