温暖洁森

勇敢做自己

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  13 随笔 :: 1 文章 :: 70 评论 :: 0 Trackbacks
     最近需要用到Quartz进行定时任务功能,通过近期研究发现,spring已经很好的集成Quartz,它主要是屏蔽了Quartz底层一些配置,使开发人员可以几乎不受到任何限制就能够利用Quartz进行定时任务的工作,这里主要是通过实例的方式对利用Spring进行Quartz定时开发的两种方式进行讲解。

1、功能需求

  需要每个30秒对系统指定目录进行扫描,把符合条件的文件进行解析入库工作,这里只提取出有关顶事任务的内容

2、研究一下Spring+Quartz结合方式,大体有两种方式可以达到定时任务功能

2.1 借助于Spring的org.springframework.scheduling.quartz.JobDetailBean的类功能,继承Spring封装Quartz的org.springframework.scheduling.quartz.QuartzJobBean类,要实现executeInternal方法,并把其中涉及到需要定时任务处理的功能放入其中


Spring配置如下:

 1    
 2        <bean id="saveProjectJob"
 3        class="org.springframework.scheduling.quartz.JobDetailBean">
 4        <property name="jobClass">
 5        <value>
 6        com.gresoft.components.fileupload.service.ParseFileQuartz
 7        </value>
 8        </property>
 9        <property name="jobDataAsMap">
10        <map>
11        <entry key="readXmlService">
12        <ref bean="readXmlService" />
13        </entry>
14        </map>
15        </property>
16        </bean>
17        <bean id="saveCron"
18        class="org.springframework.scheduling.quartz.CronTriggerBean">
19        <property name="jobDetail">
20            <ref local="saveProjectJob" />
21        </property>
22        <property name="cronExpression">
23            <value>0/30 * * * * ?</value>
24        </property>
25    </bean>
26    <bean id="scheduler"
27        class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
28        <property name="triggers">
29            <ref local="saveCron" />
30        </property>
31    </bean>

注意上述红色字体<map>结点,这里主要是为了在定时任务需要使用到Bean,通过Spring给注入进来,如果不写明,就会报
java.lang.NullPointerException错误,主要是因为没有注入Bean


方法代码如下:

 1package com.gresoft.components.fileupload.service;
 2
 3import org.quartz.JobExecutionContext;
 4import org.quartz.JobExecutionException;
 5import org.springframework.scheduling.quartz.QuartzJobBean;
 6
 7public class ParseFileQuartz extends QuartzJobBean {
 8    private readXmlService readXmlService;
 9
10    @Override
11    protected void executeInternal(JobExecutionContext jobexecutioncontext)
12            throws JobExecutionException {
13        // TODO Auto-generated method stub
14        // System.out.println(genderManager.get(1).getGenderName());
15        readXmlService.refreshFileList("D:/tomcat/webapps/sanitation/upload");
16    }

17
18    public void setReadXmlService(readXmlService readXmlService) {
19        this.readXmlService = readXmlService;
20    }

21}

22


2.2 借助于Spring 的org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean类,使用此方法使开发人员对Quartz完全透明,需要实现定时任务的方法只是一个普通方法

Spring配置文件如下:

 1<?xml version="1.0" encoding="UTF-8"?>
 2<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
 3<beans>
 4
 5    <bean id="saveProjectJob"
 6        class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
 7        <property name="targetObject">
 8            <ref local="parseQuartz" />
 9
10        </property>
11        <property name="targetMethod">
12            <value>execute</value>
13        </property>
14
15
16    </bean>
17    <bean id="parseQuartz" class="com.gresoft.components.fileupload.service.ParseFileQuartzOther">
18        <property name="readXmlService" ref="readXmlService" />
19    </bean>    
20<bean id="saveCron"
21        class="org.springframework.scheduling.quartz.CronTriggerBean">
22        <property name="jobDetail">
23            <ref local="saveProjectJob" />
24        </property>
25        <property name="cronExpression">
26            <value>0/30 * * * * ?</value>
27        </property>
28    </bean>
29    <bean id="scheduler"
30        class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
31        <property name="triggers">
32            <ref local="saveCron" />
33        </property>
34    </bean>
35

业务代码如下:

 1package com.gresoft.components.fileupload.service;
 2
 3public class ParseFileQuartzOther {
 4    private readXmlService readXmlService;
 5
 6
 7    public void execute(){
 8        // TODO Auto-generated method stub
 9        // System.out.println(genderManager.get(1).getGenderName());
10        readXmlService.refreshFileList("D:/tomcat/webapps/sanitation/upload");
11    }

12
13    public void setReadXmlService(readXmlService readXmlService) {
14        this.readXmlService = readXmlService;
15    }

16}

17

注意:在Spring配置和Quartz集成内容时,有两点需要注意
1、在<Beans>中不能够设置default-lazy-init="true",否则定时任务不触发,如果不明确指明default-lazy-init的值,默认是false。
2、在<Beans>中不能够设置default-autowire="byName"的属性,否则后台会报org.springframework.beans.factory.BeanCreationException错误,这样就不能通过Bean名称自动注入,必须通过明确引用注入。

比如上例中的parseQuartz就是明确声明注入的方式

1<bean id="parseQuartz" class="com.gresoft.components.fileupload.service.ParseFileQuartzOther">
2        <property name="readXmlService" ref="readXmlService" />
3    </bean>

具体错误信息如下:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scheduler' defined in file [D:\workspace1\sanitation\web\WEB-INF\classes\spring\quartz.xml]: Invocation of init method failed; nested exception is org.quartz.SchedulerConfigException: Failure occured during job recovery. [See nested exception: org.quartz.impl.jdbcjobstore.LockException: Failure obtaining db row lock: DB2 SQL error: SQLCODE: -204, SQLSTATE: 42704, SQLERRMC: DB2ADMIN.QRTZ_LOCKS [See nested exception: com.ibm.db2.jcc.b.SqlException: DB2 SQL error: SQLCODE: -204, SQLSTATE: 42704, SQLERRMC: DB2ADMIN.QRTZ_LOCKS]]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1362)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:
540)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$
1.run(AbstractAutowireCapableBeanFactory.java:485)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:
455)
    at org.springframework.beans.factory.support.AbstractBeanFactory$
1.getObject(AbstractBeanFactory.java:251)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:
169)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:
248)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:
170)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:
407)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:
735)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:
369)
    at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:
251)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:
190)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:
45)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:
3764)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:
4216)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:
1014)
    at org.apache.catalina.core.StandardHost.start(StandardHost.java:
736)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:
1014)
    at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:
443)
    at org.apache.catalina.startup.Embedded.start(Embedded.java:
822)
    at EmbeddedTomcat.startTomcat(EmbeddedTomcat.java:
85)
    at EmbeddedTomcat.main(EmbeddedTomcat.java:
102)
Caused by: org.quartz.SchedulerConfigException: Failure occured during job recovery. 
[See nested exception: org.quartz.impl.jdbcjobstore.LockException: Failure obtaining db row lock: DB2 SQL error: SQLCODE: -204, SQLSTATE: 42704, SQLERRMC: DB2ADMIN.QRTZ_LOCKS [See nested exception: com.ibm.db2.jcc.b.SqlException: DB2 SQL error: SQLCODE: -204, SQLSTATE: 42704, SQLERRMC: DB2ADMIN.QRTZ_LOCKS]]
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.initialize(JobStoreSupport.java:
557)
    at org.quartz.impl.jdbcjobstore.JobStoreCMT.initialize(JobStoreCMT.java:
144)
    at org.springframework.scheduling.quartz.LocalDataSourceJobStore.initialize(LocalDataSourceJobStore.java:
133)
    at org.quartz.impl.StdSchedulerFactory.instantiate(StdSchedulerFactory.java:
1204)
    at org.quartz.impl.StdSchedulerFactory.getScheduler(StdSchedulerFactory.java:
1355)
    at org.springframework.scheduling.quartz.SchedulerFactoryBean.createScheduler(SchedulerFactoryBean.java:
687)
    at org.springframework.scheduling.quartz.SchedulerFactoryBean.afterPropertiesSet(SchedulerFactoryBean.java:
582)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:
1390)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:
1359)
     
23 more
Caused by: org.quartz.impl.jdbcjobstore.LockException: Failure obtaining db row lock: DB2 SQL error: SQLCODE: -
204, SQLSTATE: 42704, SQLERRMC: DB2ADMIN.QRTZ_LOCKS [See nested exception: com.ibm.db2.jcc.b.SqlException: DB2 SQL error: SQLCODE: -204, SQLSTATE: 42704, SQLERRMC: DB2ADMIN.QRTZ_LOCKS]
    at org.quartz.impl.jdbcjobstore.StdRowLockSemaphore.executeSQL(StdRowLockSemaphore.java:
112)
    at org.quartz.impl.jdbcjobstore.DBSemaphore.obtainLock(DBSemaphore.java:
112)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:
3655)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:
3624)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.cleanVolatileTriggerAndJobs(JobStoreSupport.java:
693)
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.initialize(JobStoreSupport.java:
555)
     
31 more
Caused by: com.ibm.db2.jcc.b.SqlException: DB2 SQL error: SQLCODE: -
204, SQLSTATE: 42704, SQLERRMC: DB2ADMIN.QRTZ_LOCKS
    at com.ibm.db2.jcc.b.fg.e(fg.java:
1596)
    at com.ibm.db2.jcc.b.fg.a(fg.java:
1206)
    at com.ibm.db2.jcc.a.gb.g(gb.java:
140)
    at com.ibm.db2.jcc.a.gb.a(gb.java:
39)
    at com.ibm.db2.jcc.a.w.a(w.java:
34)
    at com.ibm.db2.jcc.a.vb.g(vb.java:
139)
    at com.ibm.db2.jcc.b.fg.n(fg.java:
1177)
    at com.ibm.db2.jcc.b.gg.eb(gg.java:
1862)
    at com.ibm.db2.jcc.b.gg.d(gg.java:
2295)
    at com.ibm.db2.jcc.b.gg.V(gg.java:
424)
    at com.ibm.db2.jcc.b.gg.executeQuery(gg.java:
407)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:
92)
    at org.quartz.impl.jdbcjobstore.StdRowLockSemaphore.executeSQL(StdRowLockSemaphore.java:
92)
     
36 more


以上就是结合Spring使用Quartz编写定时任务两种方式,Spring很好的封装使用Quartz的细节,第一种方式是利用SPring封装的Quartz类进行特定方法的实现,第二种是通过透明的使用Quartz达到定时任务开发的目的,总体说第二种对开发人员更方便!
posted on 2008-01-09 13:03 harry520 阅读(15877) 评论(6)  编辑  收藏 所属分类: J2EE

评论

# re: 实践Quartz定时任务方式大全 2008-01-10 16:03 zengzp
需要每个30秒对系统指定目录进行扫描,把符合条件的文件进行解析入库工作,对使用Quartz来定时,是否能判断文件是否写入完成?怎判断?  回复  更多评论
  

# re: 实践Quartz定时任务方式大全[未登录] 2008-01-10 16:28 harry520
我这方面业务没有讲清,我这边自动写入完成之后会把文件备份后删掉;如果解析入库有问题,备份到失败的目录中,然后删掉并把信息写入日志,我们有个日志处理系统会在那里对产生信息进行处理  回复  更多评论
  

# re: 实践Quartz定时任务方式大全 2008-01-16 20:07 王能
我这个网站http://www.yaonba.com 也是这样做的哦.   回复  更多评论
  

# re: 实践Quartz定时任务方式大全 2008-10-21 23:24 biiau
我没有设置default-lazy-init="true"这些东西,我还是报那样的错误是怎么回事呢?  回复  更多评论
  

# re: 实践Quartz定时任务方式大全 2013-05-31 14:15 hanmiao
文章中不少错别字,是不是楼主从什么地方抄过来之后,都没看壹眼就发表出来了。  回复  更多评论
  

# re: 实践Quartz定时任务方式大全 2014-10-14 10:13 萧紫飞飞
帮大忙了,还是对spring的bean注入没有深入理解  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问