array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 Spring+Quartz框架实现定时任务(集群,分布式) - 爱码网
 
1、定时任务的必要性:

定时任务在应用中的重要性不言而喻,大多是应用,特别是金融应用更是离不开定时任务,能用定时任务来处理异常订单,完成跑批,定时活动(双11)等。
在初期应用的访问量并不是那么大,一台服务器完全满足使用,但是随着用户量、业务量的逐日增加,应用中会有很多定时任务需要执行,一台服务器已经不能满足使用,
因此需要把应用给部署到集群中,前端通过nginx代理实现访问。

2、集群使用定时任务的问题:
目前大部分在集群中处理定时任务的方式不是正真的分布式处理方式,而是一种伪分布式,这种方式存在一个明显的缺陷就是当集群中机器宕机,
那么整个定时任务就会挂掉或者不能一次性跑完,会对业务产生严重的影响。

而且在集群环境中,同样的定时任务,在集群中的每台服务器都会执行,这样定时任务就会重复执行,不但会增加服务器的负担,还会因为定时任务重复执行造成额外的不可预期的错误。
解决方案是:
根据集群的数量,把定时任务中的任务平均分到集群中的每台机器上(这里的平均分是指以前多个定时任务本来是在一台机器上运行,先在人为的把这些任务分成几部分,让所有的机器分别去执行这些任务)
这就是采用了分布式定时任务来进行处理。
另外一种解决方式:
使用Quartz框架,在集群环境下,通过数据库锁机制来实现定时任务的执行,下面会介绍。


3、Quartz介绍:

Quartz是一个开放源码项目,专注于任务调度器,提供了极为广泛的特性如持久化任务,集群和分布式任务等。 
Quartz核心是调度器,还采用多线程管理。quartz框架是原生就支持分布式定时任务的。

1.持久化任务(把调度信息存储到数据):当应用程序停止运行时,所有调度信息不被丢失,当你重新启动时,调度信息还存在,这就是持久化任务。
 
2.集群和分布式处理:当在集群环境下,当有配置Quartz的多个客户端时(节点),
采用Quartz的集群和分布式处理时,我们要了解几点好处 
1) 一个节点无法完成的任务,会被集群中拥有相同的任务的节点取代执行。
2) Quartz调度是通过触发器的类别来识别不同的任务,在不同的节点定义相同的触发器的类别,这样在集群下能稳定的运行,一个节点无法完成的任务,会被集群中拥有相同的任务的节点取代执行。
3)分布式 体现在 当相同的任务定时在一个时间点,在那个时间点,不会被两个节点同时执行。

4、Quartz 在集群如何工作:

Spring+Quartz框架实现定时任务(集群,分布式)
一个 Quartz 集群中的每个节点是一个独立的 Quartz 应用,你必须对每个节点分别启动或停止。
大多数应用服务器的集群,独立的 Quartz 节点并不与另一其的节点或是管理节点通信,彼此相互独立。
Quartz 应用是通过数据库表来感知到另一应用的,调度信息存储在数据库中,当集群定时任务操作数据库(读取任务信息,更新任务信息)
数据库就会被加锁,防止其他相同的任务也读取到该任务,避免任务的重复执行。

 

5、环境搭建-创建Quartz数据库表 

因为Quartz 集群依赖于数据库,所以必须首先创建Quartz数据库表。
Quartz 包括了所有被支持的数据库平台的 SQL 脚本。在 <quartz_home>/docs/dbTables 目录下找到那些 SQL 脚本,这里的 <quartz_home> 是解压 Quartz 分发包后的目录。
Quartz 2.2.3版本,总共11张表,不同版本,表个数可能不同。数据库为mysql,用tables_mysql_innodb.sql创建数据库表,数据库不同选择的建表sql也不同,根据自己选择。

6、环境搭建-配置 Quartz 使用集群 

1.配置节点的 quartz.properties 文件

# Configure Main Scheduler Properties
# Needed to manage cluster instances
org.quartz.scheduler.instanceName = TestScheduler1   
org.quartz.scheduler.instanceId = AUTO  

# Configure ThreadPool
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true


# Configure JobStore
# Using Spring datasource in quartzJobsConfig.xml
# Spring uses LocalDataSourceJobStore extension of JobStoreCMT
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.maxMisfiresToHandleAtATime=10
org.quartz.jobStore.isClustered = true  
org.quartz.jobStore.clusterCheckinInterval = 20000

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 秒)。


7、配置applicationContext-quartz.xml文件,在这里配置任务,数据库连接等

 

 

[html] view plain copy
 
  1. <span style="font-size:14px;"><beans xmlns="http://www.springframework.org/schema/beans"  
  2.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" </span>  
[html] view plain copy
 
  1. <span style="font-size:14px;"><span style="white-space:pre">        </span>xmlns:context="http://www.springframework.org/schema/context"  
  2.         xsi:schemaLocation="http://www.springframework.org/schema/beans  
  3.         http://www.springframework.org/schema/beans/spring-beans-4.0.xsd </span>  
[html] view plain copy
 
  1. <span style="font-size:14px;"><span style="white-space:pre">        </span>http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">  
  2.   
  3.         <!-- 配置扫描的包 -->  
  4.         <context:component-scan base-package="com.clusterquartz.job" />  
  5.   
  6.         <!-- JNDI连接数据库 -->  
  7.         <bean name="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">  
  8.             <!-- tomcat -->  
  9.             <!--<property name="jndiName" value="java:comp/env/jndi/mysql/quartz"/> -->  
  10.   
  11.             <!-- jboss -->  
  12.             <property name="jndiName" value="jdbc/quartz" />  
  13.         </bean>  
  14.   
  15.         <!-- 分布式事务配置 start -->  
  16.         <!-- 配置线程池 -->  
  17.         <bean name="executor"  
  18.             class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">  
  19.             <property name="corePoolSize" value="15" />  
  20.             <property name="maxPoolSize" value="25" />  
  21.             <property name="queueCapacity" value="100" />  
  22.         </bean>  
  23.   
  24.         <!-- 配置事务管理器 -->  
  25.         <bean name="transactionManager"  
  26.             class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  27.             <property name="dataSource" ref="dataSource" />  
  28.         </bean>  
  29.   
  30.         <!-- 配置调度任务 -->  
  31.         <bean name="quartzScheduler"  
  32.             class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
  33.             <property name="configLocation" value="classpath:quartz.properties" />  
  34.             <property name="dataSource" ref="dataSource" />  
  35.             <property name="transactionManager" ref="transactionManager" />  
  36.   
  37.             <!-- 任务唯一的名称,将会持久化到数据库 -->  
  38.             <property name="schedulerName" value="baseScheduler" />  
  39.   
  40.             <!-- 每台集群机器部署应用的时候会更新触发器 -->  
  41.             <property name="overwriteExistingJobs" value="true" />  
  42.             <property name="applicationContextSchedulerContextKey" value="applicationContextKey" />  
  43.   
  44.             <property name="jobFactory">  
  45.                 <bean  
  46.                     class="com.clusterquartz.autowired.AutowiringSpringBeanJobFactory" />  
  47.             </property>  
  48.   
  49.             <property name="triggers">  
  50.                 <list>  
  51.                     <ref bean="printCurrentTimeScheduler" />  
  52.                 </list>  
  53.             </property>  
  54.             <property name="jobDetails">  
  55.                 <list>  
  56.                     <ref bean="printCurrentTimeJobs" />  
  57.                 </list>  
  58.             </property>  
  59.   
  60.             <property name="taskExecutor" ref="executor" />  
  61.   
  62.         </bean>  
  63.   
  64.         <!-- 配置Job详情,job实现业务逻辑 -->  
  65.         <bean name="printCurrentTimeJobs"  
  66.             class="org.springframework.scheduling.quartz.JobDetailFactoryBean">  
  67.             <property name="jobClass"  
  68.                 value="com.clusterquartz.job.PrintCurrentTimeJobs" />  
  69.             <property name="durability" value="true" />  
  70.             <property name="requestsRecovery" value="true" />  
  71.         </bean>  
  72.   
  73.         <!-- 配置触发时间 -->  
  74.         <bean name="printCurrentTimeScheduler"  
  75.             class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">  
  76.             <property name="jobDetail" ref="printCurrentTimeJobs" />  
  77.             <property name="cronExpression">  
  78.                 <value>0/2 * * * * ?</value>  
  79.             </property>  
  80.         </bean>  
  81.   
  82.         <!-- 分布式事务配置 end -->  
  83.   
  84.         <!-- 方式二:使用MethodInvokingJobDetailFactoryBean,任务类可以不实现Job接口,通过targetMethod指定调用方法 -->  
  85.         <!-- 定义目标bean和bean中的方法 -->  
  86.         <bean id="SpringQtzJob" class="com.clusterquartz.job.SpringQtz" />  
  87.         <bean id="SpringQtzJobMethod"  
  88.             class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">  
  89.             <property name="targetObject">  
  90.                 <ref bean="SpringQtzJob" />  
  91.             </property>  
  92.             <property name="targetMethod">  <!-- 要执行的方法名称 -->  
  93.                 <value>execute</value>  
  94.             </property>  
  95.         </bean>  
  96.         <!-- 调度触发器 -->  
  97.         <bean name="printCurrentTimeScheduler"  
  98.             class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">  
  99.             <property name="jobDetail" ref="SpringQtzJobMethod" />  
  100.             <property name="cronExpression">  
  101.                 <value>0/10 * * * * ?</value>  
  102.             </property>  
  103.         </bean>  
  104.     </beans></span>  

 

 



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

configLocation:用于指明quartz的配置文件的位置


requestsRecovery:
属性必须设置为 true,当Quartz服务被中止后,再次启动或集群中其他机器接手任务时会尝试恢复执行之前未完成的所有任务。




8、介绍相关的类:

1、

 

[html] view plain copy
 
  1. <property name="jobFactory">  
  2.     <bean  
  3.         class="com.clusterquartz.autowired.AutowiringSpringBeanJobFactory" />  
  4. </property>  

 


这个类的作用:

 

[java] view plain copy
 
  1. <span style="font-size:14px;">/** 
  2.  * @author 
  3.  * @description 使我们的任务类支持Spring的自动注入 
  4.  */  
  5. public class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory  
  6.         implements ApplicationContextAware {  
  7.     private transient AutowireCapableBeanFactory beanFactory;  
  8.   
  9.     public void setApplicationContext(ApplicationContext applicationContext)  
  10.             throws BeansException {  
  11.         beanFactory = applicationContext.getAutowireCapableBeanFactory();  
  12.     }  
  13.   
  14.     @Override  
  15.     protected Object createJobInstance(TriggerFiredBundle bundle)  
  16.             throws Exception {  
  17.         Object job = super.createJobInstance(bundle);  
  18.         beanFactory.autowireBean(job);  
  19.         return job;  
  20.     }  
  21. }</span>  

 



调用我们任务类的实现:
/**
* @author
* @description 当前任务是每隔一定时间打印当前的时间
*/
public class PrintCurrentTimeJobs extends QuartzJobBean {
private static final Log LOG_RECORD = LogFactory
.getLog(PrintCurrentTimeJobs.class);
/*
* 这里就是因为有上文中的AutowiringSpringBeanJobFactory才可以使用像@Autowired的注解,当然还可以使用Spring的其他注解
* 否则只能在配置文件中设置这属性的值,另一种方式下面说到
*/
@Autowired
private ClusterQuartz clusterQuartz;


protected void executeInternal(JobExecutionContext jobExecutionContext)
throws JobExecutionException {
LOG_RECORD.info("begin to execute task,"
+ DateUtil.dateFmtToString(new Date()));
//我们真正要执行的任务
clusterQuartz.printUserInfo();


LOG_RECORD.info("end to execute task,"
+ DateUtil.dateFmtToString(new Date()));
}
}


我们定时任务的具体逻辑实现:(我们很熟悉的Spring,注解开发)
@Service("ClusterQuartz")
public class ClusterQuartz {
private static final Logger logger = LoggerFactory
.getLogger(ClusterQuartz.class);


/*在这里可以使用spring的注解,引入各种服务之类的*/

/*@Resource(name = "miService")
private MiService miService;


@Autowired
private PushServiceI pushRecordService;*/

public void printUserInfo() {
System.out.println("定时任务的实现逻辑代码");


}
}




2、如果不配置上面1的那个property,我们的定时任务这样实现:

[java] view plain copy
 
  1. <span style="white-space:pre">      </span><span style="font-size:14px;">//执行定时任务的类  
  2.         @PersistJobDataAfterExecution  
  3.         @DisallowConcurrentExecution  
  4.         // 不允许并发执行  
  5.         public class MyQuartzJobBean1 extends QuartzJobBean {  
  6.   
  7.   
  8.             private static final Logger logger = LoggerFactory  
  9.                     .getLogger(MyQuartzJobBean1.class);  
  10.   
  11.   
  12.             @Override  
  13.             protected void executeInternal(JobExecutionContext jobexecutioncontext)  
  14.                     throws JobExecutionException {  
  15.   
  16.   
  17.                 SimpleService simpleService = getApplicationContext(jobexecutioncontext)  
  18.                         .getBean("simpleService", SimpleService.class);  
  19.                 //我们定时任务的方法       
  20.                 simpleService.testMethod1();  
  21.             }  
  22.   
  23.   
  24.             private ApplicationContext getApplicationContext(  
  25.                     final JobExecutionContext jobexecutioncontext) {  
  26.                 try {  
  27.                       
  28.                 //在这里用applicationContextSchedulerContextKey所定义的key得到对应spring 的ApplicationContext;  
  29.                     return (ApplicationContext) jobexecutioncontext.getScheduler()  
  30.                             .getContext().get("applicationContextKey");  
  31.                 } catch (SchedulerException e) {  
  32.                     logger.error(  
  33.                             "jobexecutioncontext.getScheduler().getContext() error!", e);  
  34.                     throw new RuntimeException(e);  
  35.                 }  
  36.             }  
  37.         }  
  38.   
  39.   
  40.         而定时任务的具体逻辑业务,还是和上面的一样。  
  41.         @Service("simpleService")  
  42.         public class SimpleService {  
  43.               
  44.             private static final Logger logger = LoggerFactory.getLogger(SimpleService.class);  
  45.               
  46.             public void testMethod1(){  
  47.                 //这里执行定时调度业务  
  48.                 logger.info("testMethod1.......1");  
  49.                 System.out.println("2--testMethod1......."+System.currentTimeMillis()/1000);  
  50.             }  
  51.               
  52.             public void testMethod2(){  
  53.                 logger.info("testMethod2.......2");   
  54.             }  
  55.         }</span>  



9、运行测试Quartz集群定时任务: 


public class MainTest {
public static void main(String[] args) {
ApplicationContext springContext = new ClassPathXmlApplicationContext(
new String[] { "classpath:applicationContext.xml",
"classpath:applicationContext-quartz.xml" });
}


}


10、在Spring中使用Quartz有两种方式实现:


第一种是任务类继承QuartzJobBean,第二种则是在配置文件里定义任务类和要执行的方法,类和方法仍然是普通类。
很显然,第二种方式远比第一种方式来的灵活。我们发现上面采用的就是第一种方法,下面说下第二种方法。


1、配置XML如下:

<!-- 方式二:使用MethodInvokingJobDetailFactoryBean,任务类可以不实现Job接口,通过targetMethod指定调用方法 -->
<!-- 定义目标bean和bean中的方法 -->
<bean />
</bean>

在我的资源里上传了上面实例的代码,有需要的支持下,有不当之处,望各位猿友之处,万分感谢。

相信您一定对定时任务又有了深刻的认识

每天努力一点,每天都在进步。

相关文章: