zoukankan      html  css  js  c++  java
  • Spring3整合Quartz实现定时作业

    QuartzOpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EEJ2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的日程序表。Jobs可以做成标准的Java组件或 EJBs
    Quartz是一个任务日程管理系统,一个在预先确定(被纳入日程)的时间到达时,负责执行(或者通知)其他软件组件的系统。

    Quartz用一个小Java库发布文件(.jar文件),这个库文件包含了所有Quartz核心功能。这些功能的主要接口(API)Scheduler接口。它提供了简单的操作,例如:将任务纳入日程或者从日程中取消,开始/停止/暂停日程进度。

    quartz下载: http://www.quartz-scheduler.org/download/index.html 

    Spring3中整合Quartz
    虽然Quartz已经发布了2.X版本,但是Spring3目前只能整合Quartz1.8.5及以下版本。 

    项目结构图



    1.作业调度类的实现

    package org.dennist.jobs;
    
    import org.apache.log4j.Logger;
    import org.dennist.service.SystemTimeHandler;
    /**
    *
    *   
    *
    *  @version : 1.1
    *  
    *  @author  : 苏若年          <a href="mailto:DennisIT@163.com">发送邮件</a>
    *    
    *  @since   : 1.0        创建时间:   2013-7-8       上午09:49:20
    *     
    *  TODO     : org.dennist.jobs.TimeQuartzJob.java
    *
    */
    
    public class TimeQuartzJob {
    
        private final Logger logger = Logger.getLogger(TimeQuartzJob.class);
        
        private SystemTimeHandler systemTimeHandler;
        
        public void noticeSystemTime(){
            logger.info("定时器执行,调用系统时间服务类中的系统时间通知方法");    
            systemTimeHandler.noticeSystemTime();
        }
    
        public SystemTimeHandler getSystemTimeHandler() {
            return systemTimeHandler;
        }
    
        public void setSystemTimeHandler(SystemTimeHandler systemTimeHandler) {
            this.systemTimeHandler = systemTimeHandler;
        }
        
    }

    作业调度类中调用实现了SystemTimeHandler接口的类SystemTimeHandlerImpl,实现定时向控制台输出格式化的系统时间,SystemTimeHandlerImpl的类实现如下

    package org.dennist.service.impl;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import org.apache.log4j.Logger;
    import org.dennist.jobs.TimeQuartzJob;
    import org.dennist.service.SystemTimeHandler;
    
    /**
     *
     *   
     *
     *  @version : 1.1
     *  
     *  @author  : 苏若年          <a href="mailto:DennisIT@163.com">发送邮件</a>
     *    
     *  @since   : 1.0        创建时间:   2013-7-8       上午09:55:10
     *     
     *  TODO     : org.dennist.service.impl.SystemTimeHandlerImpl.java
     *
     */
    
    public class SystemTimeHandlerImpl implements SystemTimeHandler{
    
        private final Logger logger = Logger.getLogger(TimeQuartzJob.class);
        
        public void noticeSystemTime() {
            logger.info("notice system time to all users");
            SimpleDateFormat format = new SimpleDateFormat("现在时间是: yyyy/MM/dd hh:mm:ss");
            System.out.println(format.format(new Date()).toString());
        }
    
    }

    2.Web.xml中配置spring上下文监听和quartz初始化监听

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" 
        xmlns="http://java.sun.com/xml/ns/javaee" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
        
        <display-name>spring-quartz</display-name>
        <context-param>
            <param-name>webAppRootKey</param-name>
            <param-value>quartzapp</param-value>
        </context-param>
        <context-param>
            <param-name>log4jConfigLocation</param-name>
            <param-value>classpath:log4j.properties</param-value>
        </context-param>
        <context-param>
            <param-name>log4jRefreshInterval</param-name>
            <param-value>3000</param-value>
        </context-param>
        
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-context.xml</param-value>
        </context-param>
        
        <!-- Quartz初始化监听 -->
        <listener>
            <listener-class>org.quartz.ee.servlet.QuartzInitializerListener</listener-class>
        </listener>
        
        <!-- 注入 字符编码过滤器 -->
        <filter>
            <filter-name>encodingFilter</filter-name>
            <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
            <init-param>
                <param-name>encoding</param-name>
                <param-value>UTF-8</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>encodingFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
        
        
        <welcome-file-list>
          <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
    </web-app>
    View Code

    3.contextConfigLocation指定配置文件的路径为根目录下的spring-context.xml,该配置文件中引入系统Bean实例化管理配置文件spring-beans.xml和定时任务配置类spring-jobs.xml.

    spring-context.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:p="http://www.springframework.org/schema/p"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
        
        <context:component-scan base-package="com.dennisit" />
            
        <!-- Root Context: defines shared resources visible to all other web components -->
    
        <import resource="spring-beans.xml" />
        
        <import resource="spring-jobs.xml" />    
        
    </beans>

    Bean管理配置文件spring-beans.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:p="http://www.springframework.org/schema/p"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
        
        <!-- 实例化service对象 -->
        <bean id="systemTimeHandler" class="org.dennist.service.impl.SystemTimeHandlerImpl" autowire="byType"/>
        
    </beans>

    定时作业管理配置文件spring-jobs.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: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.0.xsd 
        http://www.springframework.org/schema/task  
        http://www.springframework.org/schema/task/spring-task-3.0.xsd">
        
       <!--  
               这里加入了  
            xmlns:task="http://www.springframework.org/schema/task"  
               http://www.springframework.org/schema/task   
               http://www.springframework.org/schema/task/spring-task-3.0.xsd  
       --> 
       
           <!--  spring3.0之前的用法,配置比较繁琐 --> 
       
        <!-- 值班提醒定时器  这个是定时器要调用方法的类 -->   
        <bean id="timeNoticeJob" class="org.dennist.jobs.TimeQuartzJob" autowire="byType"/>
                
        <!-- 定义调用对象和调用对象的方法   -->     
        <bean id="timeNoticeJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
            <property name="targetObject" ref="timeNoticeJob"/> <!-- 调用的类 --> 
            <property name="targetMethod" value="noticeSystemTime" /> <!-- 调用类中的方法 --> 
            <property name="concurrent" value="true"/>   <!-- false,证明不执行并发任务 -->   
        </bean> 
        
        <!-- 定义触发时间 -->
        <bean id="timeNoticeJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
            <property name="jobDetail" ref="timeNoticeJobDetail" /> 
            <property name="cronExpression"> 
                <value>0 0/1 * * * ?</value> <!-- cron表达式 此处定义为一直触发执行任务 -->
            </property>  
        </bean> 
    
        <!-- 调度工厂,将触发时间列入; 如果将lazy-init='false'那么容器启动就会执行调度程序 -->
        <bean id="schedulerlist" lazy-init="false"
     autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
          <property name="triggers"> 
                 <list> 
                     <ref bean="timeNoticeJobTrigger"/>
                     <!-- 可以增加多个定时作业 -->
                 </list>
          </property>
        </bean>
    
     </beans>

    4.程序执行效果图,每隔一分钟在控制台打印系统时间



    说明:上面的方法是在Spring3之前用的配置方法,spring3之后使用如下方法配置,方便简单.

    <?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: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.0.xsd 
        http://www.springframework.org/schema/task  
        http://www.springframework.org/schema/task/spring-task-3.0.xsd">
        
        <!--  spring3.0之后的新用法,配置有变化,而且比以前简单了很多 --> 
    
        <!-- 定时器  这个是定时器要调用方法的类 --> 
          <bean id="timeNoticeJob" class="org.dennist.jobs.TimeQuartzJob" autowire="byType"/>
      
          <!-- 定义调用对象和调用对象的方法   --> 
          <task:scheduled-tasks>
            <!-- 调用的类TimeQuartzJob    调用类中的方法noticeSystemTime  设置每分钟调用一次-->
            <task:scheduled ref="timeNoticeJob" method="noticeSystemTime" cron="0 0/1 * * * ?" />
          </task:scheduled-tasks> 
     
     </beans>

     

    5.Quartz中的cron表达式说明

    一个cron表达式有至少6个(也可能是7个)由空格分隔的时间元素。从左至右,这些元素的定义如下:
    1.秒(0–59)
    2.分钟(0–59)
    3.小时(0–23)
    4.月份中的日期(1–31)
    5.月份(1–12或JAN–DEC)
    6.星期中的日期(1–7或SUN–SAT)
    7.年份(1970–2099) 为可选属性

    每一个元素都可以显式地规定一个值(如6),一个区间(如9-12),一个列表(如9,11,13)或一个通配符(如*)。“月份中的日期”和“星期中的日期”这两个元素是互斥的,因此应该通过设置一个问号(?)来表明你不想设置的那个字段。如下显示了一些cron表达式的例子和它们的意义:

    "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期间的每1分钟触发
    "0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发
    "0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
    "0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发
    "0 10,44 14 ? 3 WED" 每年三月的星期三的下午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" 每月的第三个星期五上午10:15触发
    "0 6 * * *"  每天早上6点
    "0 */2 * * *"每两个小时
    "0 23-7/2,8 * * *" 晚上11点到早上8点之间每两个小时,早上八点
    "0 11 4 * 1-3" 每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点
    "0 4 1 1 *" 1月1日早上4点

     
    附 录:
    Quartz中的cron表达式跟Linux中的crontab有所不同,如下为Linux中的自动化定时任务crontab命令
    基本格式 :

    *  *  *  *  *  command
    分 时 日 月 周 命令

    前五个字段可以取整数值,指定何时开始工作,第六个域是字符串,即命令字段,其中包括了crontab调度执行的命令。 各个字段之间用spaces或tabs分割。

    前5个字段分别表示:
         分钟:0-59
         小时:1-23
         日期:1-31
         月份:1-12
         星期:0-6(0表示周日)
    第6个字段表示运行的命令

    还可以用一些特殊符号:

          *:表示任何时刻
           ,:表示分割
         -:表示一个段,如第二端里: 1-5,就表示1到5点
         /n: 表示每个n的单位执行一次,如第二段里,*/1, 就表示每隔1个小时执行一次命令。也可以写成1-23/1.


    举例:

    30 21 * * * /usr/local/etc/rc.d/lighttpd restart
    上面的例子表示每晚的21:30重启apache。
    
    45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart
    上面的例子表示每月1、10、22日的4 : 45重启apache。
    
    
    10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart
    上面的例子表示每周六、周日的1 : 10重启apache。
    
    0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart
    上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。
    
    0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart
    上面的例子表示每星期六的11 : 00 pm重启apache。
    
    * */1 * * * /usr/local/etc/rc.d/lighttpd restart
    每一小时重启apache
    
    * 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart
    晚上11点到早上7点之间,每隔一小时重启apache
    
    0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart
    每月的4号与每周一到周三的11点重启apache
    
    0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart
    一月一号的4点重启apache

     
    参考文献:[ http://blog.sina.com.cn/s/blog_71420de901019jg5.html ]

    转载请注明出处:[ http://www.cnblogs.com/dennisit/p/3177800.html ]

     

  • 相关阅读:
    HDOJ 4747 Mex
    HDU 1203 I NEED A OFFER!
    HDU 2616 Kill the monster
    HDU 3496 Watch The Movie
    Codeforces 347A A. Difference Row
    Codeforces 347B B. Fixed Points
    Codeforces 372B B. Hungry Sequence
    HDU 1476 Sudoku Killer
    HDU 1987 How many ways
    HDU 2564 词组缩写
  • 原文地址:https://www.cnblogs.com/dennisit/p/3177800.html
Copyright © 2011-2022 走看看