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 ]

     

  • 相关阅读:
    Mac小知识点
    UIScrollView直接在StoryBoard中拖控件
    iOS小工具
    iOS设备信息
    Android Studio stuck on “Gradle: resolve dependancies '_debugCompile'” or 'detachedConfiguration1'
    iOS开发插件集
    Include guards
    oc单例
    Java反射中与自动装箱有关的坑及其解决方案
    ByxAOP——简易AOP框架
  • 原文地址:https://www.cnblogs.com/dennisit/p/3177800.html
Copyright © 2011-2022 走看看