定时任务Timer、Quartz实战与详解

 

配置文件

<?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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        "
       default-autowire="byName">
    <!--   0 0 */2 * * ? 每两小时、整点触发 -->
    <!--   0 0/2 * * * ? 每两分钟  -->
    <!--   0/5 * * * * ? 每五秒钟  -->
    <!--   0 15 10 * * ? 每天Y分X点触发  -->
    <!-- 0 0 12 * * ?	在每天中午12:00触发
        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:00至2:59之间每分钟触发一次
        0 0/5 14 * * ?	每天在下午2:00至2:59之间每5分钟触发一次
        0 0/5 14,18 * * ?	每天在下午2:00至2:59和6:00至6:59之间的每5分钟触发一次
        0 0-5 14 * * ?	每天在下午2:00至2:05之间每分钟触发一次
        0 10,44 14 ? 3 WED	每三月份的星期三在下午2:00和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, 2003, 2004 and 2005年的每个月的最后一个星期五的上午10:15触发
        0 15 10 ? * 6#3	在每个月的第三个星期五的上午10:15触发
        0 0 12 1/5 * ?	从每月的第一天起每过5天的中午12:00时触发
        0 11 11 11 11 ?	在每个11月11日的上午11:11时触发.  -->
    <!--创建自定义任务类-->
    <bean id="startNotifyTask" class="com.alibaba.meeting.task.StartNotifyTask">
        <property name="source" value="${meeting.work.source}"></property>
        <property name="action" value="${meeting.work.action.notify}"></property>
        <property name="executeMachineName" value="${meeting.execute_machine_name}"></property>
    </bean>
    <!--创建任务详情对象-->
    <bean id="jobStartNotify" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <!--注入任务类-->
        <property name="targetObject" ref="startNotifyTask"/>
        <!--任务类中执行的任务方法-->
        <property name="targetMethod">
            <value>run</value>
        </property>
        <property name="concurrent" value="false"/>
    </bean>
    <!--创建触发器对象-->
    <bean id="cronStartNotify" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <!--注入任务详情对象-->
        <property name="jobDetail" ref="jobStartNotify"/>
        <!--注入corn表达式-->
        <property name="cronExpression">
            <value>0 0/1 * * * ?</value>
        </property>
    </bean>


    <!--创建自定义任务类-->
    <bean id="taskEndNotify" class="com.alibaba.meeting.task.EndNotifyTask">
        <property name="source" value="${meeting.work.source}"></property>
        <property name="action" value="${meeting.work.action.notifyEnd}"></property>
        <property name="executeMachineName" value="${meeting.execute_machine_name}"></property>
    </bean>
    <!--创建任务详情对象-->
    <bean id="jobEndNotify" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <!--注入任务类-->
        <property name="targetObject" ref="taskEndNotify"/>
        <!--任务类中执行的任务方法-->
        <property name="targetMethod">
            <value>run</value>
        </property>
        <property name="concurrent" value="false"/>
    </bean>
    <!--创建触发器对象-->
    <bean id="cronEndNotify" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <!--注入任务详情对象-->
        <property name="jobDetail" ref="jobEndNotify"/>
        <!--注入corn表达式-->
        <property name="cronExpression">
            <value>0 0/1 * * * ?</value>
        </property>
    </bean>


    <!--创建自定义任务类-->
    <bean id="taskCostSettle" class="com.alibaba.meeting.task.CostSettleTask">
        <property name="source" value="${meeting.work.source}"></property>
        <property name="action" value="${meeting.work.action.costsettle}"></property>
        <property name="executeMachineName" value="${meeting.execute_machine_name}"></property>
    </bean>
    <!--创建任务详情对象-->
    <bean id="jobCostSettle" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <!--注入任务类-->
        <property name="targetObject" ref="taskCostSettle"/>
        <!--任务类中执行的任务方法-->
        <property name="targetMethod">
            <value>run</value>
        </property>
        <property name="concurrent" value="false"/>
    </bean>
    <!--创建触发器对象-->
    <bean id="cronCostSettle" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <!--注入任务详情对象-->
        <property name="jobDetail" ref="jobCostSettle"/>
        <!--注入corn表达式-->
        <property name="cronExpression">
            <value>0 0/1 * * * ?</value>
        </property>
    </bean>

    <!--会议结束后生成订单-->
    <bean id="createOrderTask" class="com.alibaba.meeting.task.CreateOrderTask">
        <property name="executeMachineName" value="${meeting.execute_machine_name}"></property>
    </bean>
    <bean id="jobcreateOrderTask" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="createOrderTask"/>
        <property name="targetMethod">
            <value>run</value>
        </property>
        <property name="concurrent" value="false"/>
    </bean>
    <bean id="croncreateOrderTask" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <property name="jobDetail" ref="jobcreateOrderTask"/>
        <property name="cronExpression">
            <value>0 31 * * * ?</value>
        </property>
    </bean>
    <bean id="croncreateOrderTask2" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <property name="jobDetail" ref="jobcreateOrderTask"/>
        <property name="cronExpression">
            <value>0 1 */1 * * ?</value>
        </property>
    </bean>
    <!--创建任务调度对象-->
    <bean autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <!--注入触发器-->
        <property name="triggers">
            <list>
                <ref bean="cronStartNotify"/>
                <ref bean="cronEndNotify"/>
                <ref bean="cronCostSettle"/>
                <ref bean="croncreateOrderTask"/>
                <ref bean="croncreateOrderTask2"/>
            </list>
        </property>
    </bean>

</beans>

会议结束后生成订单com.baizhi.meeting.task.CreateOrderTask.java文件

package com.baizhi.meeting.task;

import com.baizhi.meeting.manager.BookInfoManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * Created by jrs on 16-7-25.
 */
public class CreateOrderTask extends CheckTask {
    private Logger logger = LoggerFactory.getLogger(CreateOrderTask.class);

    @Autowired
    private BookInfoManager bookInfoManager;

    public void run() {
        if(checkExecuteMachine()) {
            logger.info("CreateOrderTask start");
            bookInfoManager.createNotPayOrder();
            logger.info("CreateOrderTask end");
        }
    }
}

checkTask.java

package com.baizhi.meeting.task;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetAddress;
import java.net.UnknownHostException;


public class CheckTask {

    private final Logger log = LoggerFactory.getLogger(CheckTask.class);
    private String executeMachineName;

    public String getExecuteMachineName() {
        return executeMachineName;
    }

    public void setExecuteMachineName(String executeMachineName) {
        this.executeMachineName = executeMachineName;
    }

    /**
     * 判断执行的机器
     *
     * @return
     */
    public boolean checkExecuteMachine() {
        String currentMachineName = getCurrentMachineName();
        if (currentMachineName.equals(executeMachineName)) {
            return true;
        }
        log.info("不能在[" + currentMachineName + "] 这台机器上执行任务,只能在[" + executeMachineName + "]上执行");
        return false;
    }

    private String getCurrentMachineName() {
        InetAddress addr;
        String hostName = "";
        try {
            addr = InetAddress.getLocalHost();
            hostName = addr.getHostName();
        } catch (UnknownHostException e) {
            return "";
        }
        return hostName;
    }
}

Timer定时任务

1. Java中专门做定时的工具类Timer

        1.注意:在测Java工具类Timer时,不能用JUnit测试来测。

          原因是:用JUnit发布webService时,服务听不下来(用main函数发布)。JUint测试Timer定时,服务                         听 不下来(用main函数发布)。

        2.Timer这个类是java.util下的一个类,不是抽象类,也不是接口,所以可以直接new类的对象,Timer             timer= new Timer();这样就创建了一个定时任务的对象。

        3.对象中有一个schedule方法。要告诉对象,要调度那些任务,这些任务什时候开始执行,什么时间              结束,时重复执行,执行几次,是执行一次,还是执行多次。 

2. java中的工具类Timer,执行定时周期

        1.方法schedule参数的意思:

            

            TimerTask(){}:定时执行的任务。

 

             new Date():开始执行时间。

             1000:周期执行的时间间隔。注意:时间单位为毫秒。

 

3. 代码解析

              

 

4. Timer工具类的缺点

      缺点:不能很好的解决项目中,复杂的业务,比如,某一天的某一整点运行,或者这一年的几个时间点                   去运行。那么就需要进行复杂时间的计算,但有是也没法达到效果。

5.Java项目直接转为web项目

                 

 

6. Timer与web项目的集成

            会把定时任务放到我们的监听器中执行。监听器去实现servletContextListener接口,监听器中有两         个方法,一个是初始化ContextInitialized,一个是销毁ContextDestoryed。所以定时任务要在初始化         方法中做。只要初始化了监听器,就会执行定时任务。日后为了类的复用。我们自己写一个MyTask类         去继承TimerTask。

      1.自定义定时任务

            

 

        2.自定义监听器

                

 

          3.监听器在web.xml中的配置

                

 

7. 注意

                Quartz定时任务

1. Quartz是一个开源的定时任务框架.

2. What is Quartz?
              Job Scheduling(调度) Library(库)

       Quartz is a richly(丰富地) featured, open source job scheduling library that can be integrated(集成) within virtually any Java application - from the smallest stand-alone(桌面级) application(应用) to the largest e-commerce(电商) system. Quartz can be used to create simple or complex schedules for executing tens, hundreds, or even tens-of-thousands of jobs; jobs whose tasks are defined as standard Java components that may execute virtually anything you may program them to do. The Quartz Scheduler includes many enterprise-class features, such as support for JTA transactions and clustering.

Quartz is freely usable, licensed under the Apache 2.0 license.

              

 

3.         Quartz在非web中的应用

       版本一:

      1.自定义任务类必须实现quartz规定的Job接口

                

 

      2.很少用测试

                  

 

      版本二:

      1.自定义任务类必须实现quartz规定的Job接口

                    

 

      2.常用测试

                     

 

      3.Cron表达式的生成

                       

 

                         

4.Quartz与Spring的整合

          1.环境的搭建,相关jar包

          2.自定义任务

                         

 

         3.Spring配置文件的配置

                        

 

4.测试代码

                   

 

5.注意:

            1.自定义任务中,不能执行多个方法。

            2.必须为每个任务详情对像在创建一次对象。

转载于:https://my.oschina.net/u/185811/blog/891253

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值