Spring3.0.6定時任務task:scheduled


項目使用的spring版本比較舊是3.0.6版本,由於需要進行定時任務,就決定使用Spring自帶的scheduled task。

在網上找了很多文章,也查看了Spring3.0.6的官方文檔,按照網上和文檔所說,可以使用注解或者配置兩種方法之一都行,但是我發現單獨使用兩種方法都不行,怎么配置任務都無法運行。

最后看到一篇文章說兩種方法同時用,才成功執行定時任務,可能是個Bug,我試了下,同時使用注解和XML配置后,任務確實成功執行了。

XML配置中,只需要配置一個方法即可,其他方法也能跟着運行了,而且XML中配置的定時時間會被注解覆蓋掉,只能先這么做了,期待高手解答原因。

難道真的是Spring3.0.6的Bug??

Spring配置如下:

 

[html]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.        xmlns:jee="http://www.springframework.org/schema/jee"  
  4.        xmlns:tx="http://www.springframework.org/schema/tx"  
  5.        xmlns:context="http://www.springframework.org/schema/context"  
  6.        xmlns:aop="http://www.springframework.org/schema/aop"  
  7.        xmlns:task="http://www.springframework.org/schema/task"  
  8.        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  9.        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
  10.        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd  
  11.        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd  
  12.        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd  
  13.        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"  
  14.        default-lazy-init="true" default-autowire="byName">  
  15.   
  16.     <!-- 配置注解掃描 -->  
  17.     <context:annotation-config />  
  18.   
  19.     <!-- 自動掃描的包名 -->  
  20.     <context:component-scan base-package="com.demo" />  
  21.   
  22.     <!-- Spring定時器注解開關-->  
  23.     <task:annotation-driven />  
  24.     <!-- 此處對於定時時間的配置會被注解中的時間配置覆蓋,因此,以注解配置為准 -->  
  25.     <task:scheduled-tasks scheduler="myScheduler">  
  26.         <task:scheduled ref="scheduledTaskManager" method="autoCardCalculate" cron="1/5 * * * * *"/>  
  27.     </task:scheduled-tasks>  
  28.     <task:scheduler id="myScheduler" pool-size="10"/>  
  29.   
  30.     <aop:aspectj-autoproxy />  
  31.   
  32.     <!-- 加載配置文件 -->  
  33.     <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
  34.         <property name="locations">  
  35.             <list>  
  36.                 <value>classpath:config.properties</value>  
  37.             </list>  
  38.         </property>  
  39.     </bean>  
  40. </beans>  

 

執行任務的POJO類如下:

 

[java]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1. package com.demo.schedule;  
  2.   
  3. import org.apache.log4j.Logger;  
  4. import org.springframework.beans.factory.annotation.Autowired;  
  5. import org.springframework.scheduling.annotation.Scheduled;  
  6. import org.springframework.stereotype.Component;  
  7. import java.util.Date;  
  8. /** 
  9.  * Created with IntelliJ IDEA. 
  10.  * Author:  
  11.  * Date: 2013-10-09 14:39 
  12.  * Function: Spring定時任務管理 
  13.  */  
  14. @Component("scheduledTaskManager")  
  15. public class ScheduledTaskManager {  
  16.     /** 
  17.      * cron表達式:* * * * * *(共6位,使用空格隔開,具體如下) 
  18.      * cron表達式:*(秒0-59) *(分鍾0-59) *(小時0-23) *(日期1-31) *(月份1-12或是JAN-DEC) *(星期1-7或是SUN-SAT) 
  19.      */  
  20.   
  21.     /** 
  22.      * 定時卡點計算。每天凌晨 02:00 執行一次 
  23.      */  
  24.     @Scheduled(cron = "0 0 2 * * *")  
  25.     public void autoCardCalculate() {  
  26.         System.out.println("定時卡點計算... " + new Date());  
  27.     }  
  28. }  


對於這個問題,期待高手解答,也希望大家能一起討論下。

 

替換成Sping3.2.2之后,就可以直接在XML中配置,而不需要在方法上使用注解配置時間了。

 

感謝4樓,5樓解答

問題在於Spring全局配置:default-lazy-init="true"
加上這一句啟動的時候還怎么初始化,如果不想改這個配置,那在bean上加個注解
@Component("scheduledTaskManager") 
@Lazy(value="false")
public class ScheduledTaskManager { 
  //TODO 
}

 

 

                           來源:http://blog.csdn.net/zht666/article/details/12518711

 

 

 

 

 

 

 

 

 

 

 

 

 

//---------------------------------------------------------

【Spring】Spring的定時任務

 

> 參考的優秀文章

Task Execution and Scheduling

 

> 版本說明

復制代碼
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>3.2.14.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.webflow</groupId>
        <artifactId>spring-webflow</artifactId>
        <version>2.3.4.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.1.0</version>
    </dependency>
</dependencies>
復制代碼

 

> 搭建最簡單的Spring定時任務工程

Spring定時任務,給人的第一感覺就是簡潔(>_<)

所需要的JAR,參考以上“版本說明”的POM文件,當然,不嫌麻煩,也可以一個個去下載。

把Spring通過web.xml注冊進來

復制代碼
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:spring/spring.xml</param-value>
</context-param>

<listener>
    <description>Spring Context</description>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
復制代碼

 

當然,需要告訴Spring去哪兒掃描組件。對了,也要告訴Spring我們是使用注解方式注冊任務的

復制代碼
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
           http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">

    <context:component-scan base-package="com.nicchagil.*"/>
    <task:annotation-driven/>
    
</beans>
復制代碼

 

附logback的配置

復制代碼
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder 
            by default -->
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
            </pattern>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>D:/logs/application.log</file>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
            </pattern>
        </encoder>
    </appender>

    <root level="debug">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE" />
    </root>
</configuration>
復制代碼

 

好了,注冊一個簡單的任務,它每逢0秒執行,打印一個語句

復制代碼
package com.nicchagil.springtask;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class MyFirstSpringJob {
    
private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Scheduled(cron = "0 * * * * ?")
    public void run() {
        logger.info("MyFirstSpringJob trigger...");
    }

}
復制代碼

 

如無意外,啟動項目后,可見日志大致如下

22:42:00.024 [pool-1-thread-1] INFO  c.n.springtask.MyFirstSpringJob - MyFirstSpringJob trigger...
22:43:00.002 [pool-1-thread-1] INFO  c.n.springtask.MyFirstSpringJob - MyFirstSpringJob trigger...

 

> 如果你同時執行多個任務,且某些任務耗時較長,要配線程池哦(>_<)

如題。比如,你設置了12:00觸發A任務、12:05觸發B任務,如果A任務需耗時10分鍾,並且沒設置線程池,那么B任務有可能會被推遲到12:10以后再執行哦。

所以,這些情況,我們需設置線程池

<task:annotation-driven scheduler="myScheduler"/>
<task:scheduler id="myScheduler" pool-size="20"/>

:具體池的大小,視項目情況而定

 

將任務改為如下測試

第一個任務

復制代碼
package com.nicchagil.springtask;

import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class MyFirstSpringJob {
    
private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Scheduled(cron = "0 * * * * ?")
    public void run() {
        logger.info("MyFirstSpringJob trigger...");
        
        /* 模擬此Job需耗時5秒 */
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
復制代碼

 

第二個任務

復制代碼
package com.nicchagil.springtask;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class MySecondSpringJob {
    
private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Scheduled(cron = "3 * * * * ?")
    public void run() {
        logger.info("MySecondSpringJob trigger...");
    }

}
復制代碼

 

由日志可以看出,第一個任務由一個線程執行;而第二個任務啟動時,由於第一個任務還未完成,則由另外一個線程執行

22:49:00.023 [myScheduler-1] INFO  c.n.springtask.MyFirstSpringJob - MyFirstSpringJob trigger...
22:49:03.002 [myScheduler-2] INFO  c.n.springtask.MySecondSpringJob - MySecondSpringJob trigger...

 

作者:Nick Huang 博客:http://www.cnblogs.com/nick-huang/ 本博客為學習、筆記之用,以筆記形式記錄學習的知識與感悟。學習過程中可能參考各種資料,如覺文中表述過分引用,請務必告知,以便迅速處理。如有錯漏,不吝賜教。
 
 
來源:http://www.cnblogs.com/nick-huang/p/4864737.html
 
 
 
==================
==================
==================
 定時任務的方法不能有參數。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM