溫暖潔森

          勇敢做自己

            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 閱讀(15905) 評論(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注入沒有深入理解  回復  更多評論
            

          主站蜘蛛池模板: 潢川县| 亳州市| 平阳县| 育儿| 大石桥市| 申扎县| 察哈| 白山市| 新乡市| 都兰县| 永寿县| 沙田区| 洛扎县| 易门县| 郁南县| 雷山县| 清丰县| 南乐县| 奉化市| 吐鲁番市| 宁城县| 石棉县| 阳曲县| 金阳县| 莒南县| 乌鲁木齐市| 呼玛县| 南丹县| 金华市| 西林县| 称多县| 容城县| 黄浦区| 许昌县| 澄迈县| 正安县| 县级市| 平潭县| 东海县| 鹤岗市| 乌海市|