Spring 4.3.5 配置 quartz 2.2.1 任务调度遇到的问题和解决方法

Spring版本:4.3.5.RELEASE

quartz版本:2.2.1

 

1. 基本配置

(1)配置自己写的任务类

Xml代码 
  1. <bean id="testTimer"     class="org.linkscholar.biz.timer.TestTimer" />  

 (2)配置JobDetail

Xml代码  
  1. <bean id="testJobDetail"  
  2.         class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">  
  3.         <property name="targetObject">  
  4.             <ref bean="testTimer"/>  
  5.         </property>  
  6.         <property name="targetMethod">  
  7.             <value>scan</value>  
  8.         </property>  
  9.     </bean>  

 targetObject指定任务对象,targetMethod指定对象执行方法

(3)配置触发器

Xml代码  
  1. <bean id="testCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">  
  2.         <property name="jobDetail">  
  3.             <ref bean="testJobDetail" />  
  4.         </property>  
  5.         <property name="cronExpression">  
  6.             <value>0 0/1 * * * ?</value>  
  7.         </property>  
  8.     </bean>  

 这里 0 0/1 * * * ? 表示每一分钟执行一次,关于调用时间的具体配置可以参照

http://jingyan.baidu.com/article/0f5fb099cc244d6d8234ea6b.html

(4)配置总管理类

Xml代码  
  1. <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"  lazy-init="false">  
  2.         <property name="triggers">  
  3.             <list>  
  4.                 <ref local="testCronTrigger" />  
  5.             </list>  
  6.         </property>  
  7.     </bean>  

 lazy-init="false"表示容器启动就开始执行调度任务, 这里可以配置多个触发器,可以统一管理

 

2. 出现的问题

按照上述配置后,写了Junit测试运行,发现出现错误:

(1)

Cannot find class [org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean] for bean with name

这个异常就是上面这个类找不到,开始我到spring-context.jar中去找,虽然有org.springframework.scheduling这个包,但是却没有quartz,后来上网查了好久才知道,上面这个类在spring-contex-support这个包中(以前spring用一个jar,后来分成了多个jar包),引入进来就对了。

如下所示(pom.xml)


<dependency>
      <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
     <version>4.3.5.RELEASE</version>
</dependency>

<dependency>  
   <groupId>org.quartz-scheduler</gro upId>
   <artifactId>quartz</artifactId>  
   <version>2.2.1</version>
</dependency>
<dependency>


(2)

解决了上面的问题后,又出现一个新的错误:

java.lang.IncompatibleClassChangeError: class org.springframework.scheduling.quartz.CronTriggerBean has interface org.quartz.CronTrigger as super class  

这是因为版本不兼容引起的,解决的办法是:

1. 降低quartz到1.x版本

2. 根据spring的建议将原来的xxxTriggerBean替换成xxxTriggerFactoryBean,这里就是将配置中的第三步配置触发器类CronTriggerBean换成CronTriggerFactoryBean:

Xml代码  
  1. <bean id="testCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">  
  2.         <property name="jobDetail">  
  3.             <ref bean="testJobDetail" />  
  4.         </property>  
  5.         <property name="cronExpression">  
  6.             <value>0 0/1 * * * ?</value>  
  7.         </property>  
  8.     </bean>  

完整的quartz的 xml代码参考如下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
	<!-- background job implementation -->
	<bean id="countMonitorJob" class="com.letv.ofc.worker.CountMonitorJob">
	</bean>
	<bean id="toHistoryMultiJob" class="com.letv.ofc.worker.ToHistoryMultiJob">
	</bean>

	<!-- job workers definition of Spring Cron -->
	<bean id="orderStatJobWorker"
		class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
		<property name="targetObject">
			<ref bean="orderStatisticsJob" />
		</property>
		<property name="targetMethod">
			<value>exeute</value>
		</property>
		<property name="concurrent" value="false" />
	</bean>

	<bean id="countMonitorJobWorker"
		class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
		<property name="targetObject">
			<ref bean="countMonitorJob" />
		</property>
		<property name="targetMethod">
			<value>countMonitor</value>
		</property>
		<property name="concurrent" value="false" />
	</bean>

	<bean id="toHistoryMultiJobWorker"
		class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
		<property name="targetObject">
			<ref bean="toHistoryMultiJob" />
		</property>
		<property name="targetMethod">
			<value>toHistoryMulti</value>
		</property>
		<property name="concurrent" value="false" />
	</bean>

	<!-- Job workers' triggers definition -->

	<bean id="orderStatisticsTrigger"
		class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
		<property name="jobDetail">
			<ref bean="orderStatJobWorker" />
		</property>
		<property name="cronExpression">
			<value>${worker_keeper_time}</value>
		</property>
	</bean>

	<bean id="countMonitorTrigger"
		class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
		<property name="jobDetail">
			<ref bean="countMonitorJobWorker" />
		</property>
		<property name="cronExpression">
			<value>${worker_keeper_time}</value>
		</property>
	</bean>

	<bean id="toHistoryMultiJobTrigger"
		class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
		<property name="jobDetail">
			<ref bean="toHistoryMultiJobWorker" />
		</property>
		<property name="cronExpression">
			<value>${worker_ToHistory}</value>
		</property>
	</bean>

	<!-- all worker register themselves to the factory here as only one entry 
		point -->
	<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<property name="dataSource">
			<null />
		</property>
		<property name="triggers">
			<list>
				<ref bean="toHistoryMultiJobTrigger" />
				<ref bean="countMonitorTrigger" />
				<ref bean="orderStatisticsTrigger" />
			</list>
		</property>
	</bean>
</beans>

 上面的xml在spring 4.3.5.RELEASE和quartz 2.2.1下工作很好。

(3) 

解决了上面两个问题后,发现又有错误:

Table 'database.qrtz_locks' doesn't exist

这个错误看起来匪夷所思。。。

 参考:

http://blog.sina.com.cn/s/blog_6151984a0100o42e.html

SchedulerFactoryBean试图访问数据库获取quartz的一些管理表信息,自然访问数据库时需要注入dataSource bean,当缺省autowire为no,则没有dataSource bean被注入,quartz会认为项目没连数据库,会BYPASS这个访问管理表的功能. 当你配置了default-autowire=byName时,dataSource bean被自动注入,这时quartz认为项目既然能连到数据库,就想当然的认为对应的那些表一定存在,没找到时就出异常.

 

 

解决办法:

1.  去掉default-autowire=byName(这种方法估计不是很愿意,得损失很多便利)

2. 在数据库中创建相应的数据表(这种需要创建很多表,而且建这些表可能我们暂时也用不到)

3. 在SchedulerFactoryBean这个bean配置中关掉autoware,加入autorware=“no”(这个解决方法好!):

Xml代码  
  1. <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"  lazy-init="false" autoware="no">  
  2.         <property name="triggers">  
  3.             <list>  
  4.                 <ref local="testCronTrigger" />  
  5.             </list>  
  6.         </property>  
  7.     </bean>  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值