欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring3 Schedule Task之注解实现 (两次起步Schedule Task 的解决方案)

程序员文章站 2022-05-11 16:30:59
...
Spring3 Schedule Task之注解实现 (两次启动Schedule Task 的解决方案)
在spring3 中的新引入的task 命名空间。可以部分取代 quartz 功能,配置和API更加简单,并且支持注解方式。但是如果需要使用比较复杂的任务调度。还是建议使用quartz。


第一步:
        在Spring的相关配置文件中(applicationContext.xml或者是{project_name}_servelt.xml或者是独立的配置文件如XXX_quartz.xml)中配置并开启Spring Schedule Task.注意其中高亮的部分是必须的。

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:p="http://www.springframework.org/schema/p"
       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.1.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
       http://www.springframework.org/schema/task
       http://www.springframework.org/schema/task/spring-task-3.0.xsd
       ">
    <mvc:annotation-driven />

    <context:component-scan base-package="com.mytools.validator.engine" />
   
    <!-- 启动定时器 -->
    <task:annotation-driven/>    
</beans>

第二步:
        可以在类中的需要定时执行的方法下指定如下Annotation
@Scheduled(cron="0 33/3 * * * ?") //每小时的33分钟开始执行,每3分钟执行1次
    public void start() throws ServletException {
                 validate();
}
备注:其实@Scheduled中可以指定如下3中时间表达式:
(1)fixedRate:每隔多少毫秒执行一次该方法。如:

          @Scheduled(fixedRate=2000)  // 每隔2秒执行一次
          public void scheduleMethod(){ 
                    System.out.println("Hello world..."); 
          } 
     (2)fixedDelay:当一次方法执行完毕之后,延迟多少毫秒再执行该方法。
 
  (3)cron:详细配置了该方法在什么时候执行。cron值是一个cron表达式。如:

                @Scheduled(cron="0 0 0 * * SAT") 
                public voidarchiveOldSpittles() { 
                 // ... 
                }


到指定时间后,任务总是执行2次的解决方案:
这是因为我们很容易在一个基于Spring的Web工程中启动2个定时线程:
第一次:web容器启动的时候,读取applicationContext.xml(或者别的Spring核心配置文件)文件时,会加载一次。

第二次:Spring本身会加载applicationContext.xml(或者别的Spring核心配置文件)一次。

解决方案:将你的Task的相关配置独立出来并在web.xml中通过context-param加载。而不是通过spring加载。
1) 独立出Spring-Task,如新命名一个文件名叫cms_quartz.xml
2)    在web.xml中去加载该文件:
<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/cms-servlet.xml,classpath:cms-quartz.xml</param-value>
    </context-param>



*********************************

1.首先加入下载spring3.2 ,http://projects.spring.io/spring-framework/

2.加入jar包,在applicationContext.xml加入声明

-xmlns加入

[java
xmlns:task="http://www.springframework.org/schema/task" 
-xsi加入
[java] 
http://www.springframework.org/schema/task  
[java]
http://www.springframework.org/schema/task/spring-task-3.2.xsd" 

[java]
<!-- 使用Annotation自动注册Bean,解决事物失效问题:在主容器中不扫描@Controller注解,在SpringMvc中只扫描@Controller注解。  --> 
<context:component-scan base-package="com.zt49"> 
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> 
</context:component-scan> 

任务注解

[java] 
<task:annotation-driven /> 

3.创建一个任务类(示例)
[java]
import org.springframework.context.annotation.Lazy; 
import org.springframework.scheduling.annotation.Scheduled; 
import org.springframework.stereotype.Component; 
 
@Component 
public class TestTask { 
     
    @Scheduled(cron = "0 0/1 * * * ?") 
    public void test(){ 
        System.out.println("test"); 
    } 
 

启动程序,定时任务就可以了。这个示例代表每分钟执行一次任务。

附:cron常用表示:

CronTrigger配置格式:
   格式: [秒] [分] [小时] [日] [月] [周] [年]
序号 说明 是否必填 允许填写的值 允许的通配符
1   秒    是      0-59 ,         - * /
2    分    是      0-59 ,        - * /
3    小时  是      0-23 ,       - * /
4    日    是      1-31 ,      - * ? / L W
5    月    是    1-12 or JAN-DEC , - * /
6    周     是     1-7 or SUN-SAT , - * ? / L #
7    年     否     empty 或 1970-2099 , - * /

通配符说明:
* 表示所有值. 例如:在分的字段上设置 "*",表示每一分钟都会触发。
? 表示不指定值。使用的场景为不需要关心当前设置这个字段的值。例如:要在每月的10号触发一个操作,但不关心是周几,所以需要周位置的那个字段设置为"?" 具体设置为 0 0 0 10 * ?
- 表示区间。例如在小时上设置 "10-12",表示 10,11,12点都会触发。
, 表示指定多个值,例如在周字段上设置 "MON,WED,FRI" 表示周一,周三和周五触发
/ 用于递增触发。如在秒上面设置"5/15" 表示从5秒开始,每增15秒触发(5,20,35,50)。 在月字段上设置'1/3'所示每月1号开始,每隔三天触发一次。
L 表示最后的意思。在日字段设置上,表示当月的最后一天(依据当前月份,如果是二月还会依据是否是润年[leap]), 在周字段上表示星期六,相当于"7"或"SAT"。如果在"L"前加上数字,则表示该数据的最后一个。例如在周字段上设置"6L"这样的格式,则表示“本 月最后一个星期五"
W 表示离指定日期的最近那个工作日(周一至周五). 例如在日字段上设置"15W",表示离每月15号最近的那个工作日触发。如果15号正好是周六,则找最近的周五(14号)触发, 如果15号是周未,则找最近的下周一(16号)触发.如果15号正好在工作日(周一至周五),则就在该天触发。如果指定格式为 "1W",它则表示每月1号往后最近的工作日触发。如果1号正是周六,则将在3号下周一触发。(注,"W"前只能设置具体的数字,不允许区间"-").
小提示
'L'和 'W'可以一组合使用。如果在日字段上设置"LW",则表示在本月的最后一个工作日触发(一般指发工资 )
# 序号(表示每月的第几个周几),例如在周字段上设置"6#3"表示在每月的第三个周六.注意如果指定"#5",正好第五周没有周六,则不会触发该配置(用 在母亲节和父亲节再合适不过了)
小提示
周字段的设置,若使用英文字母是不区分大小写的 MON 与mon相同.

常用示例:
0 0 12 * * ? 每天12点触发
0 15 10 ? * * 每天10点15分触发
0 15 10 * * ? 每天10点15分触发
0 15 10 * * ? * 每天10点15分触发
0 15 10 * * ? 2005 2005年每天10点15分触发
0 * 14 * * ? 每天下午的 2点到2点59分每分触发
0 0/5 14 * * ? 每天下午的 2点到2点59分(整点开始,每隔5分触发)
0 0/5 14,18 * * ? 每天下午的 2点到2点59分(整点开始,每隔5分触发) 每天下午的 18点到18点59分(整点开始,每隔5分触发)
0 0-5 14 * * ? 每天下午的 2点到2点05分每分触发
0 10,44 14 ? 3 WED 3月分每周三下午的 2点10分和2点44分触发
0 15 10 ? * MON-FRI 从周一到周五每天上午的10点15分触发
0 15 10 15 * ? 每月15号上午10点15分触发
0 15 10 L * ? 每月最后一天的10点15分触发
0 15 10 ? * 6L 每月最后一周的星期五的10点15分触发
0 15 10 ? * 6L 2002-2005 从2002年到2005年每月最后一周的星期五的10点15分触发
0 15 10 ? * 6#3 每月的第三周的星期五开始触发
0 0 12 1/5 * ? 每月的第一个中午开始每隔5天触发一次
0 11 11 11 11 ? 每年的11月11号 11点11分触发




转载:http://www.myexception.cn/industry/1491076.html
相关标签: spring Schedule