zoukankan      html  css  js  c++  java
  • 轻松搞定Spring+quartz的定时任务

    1.spring 的定时任务写法有两种:一种是继承工作类,一种是普通的Bean,定时写法有两种写法:一种是以时间间隔启动任务SimpleTriggerBean,一种是以时刻启动任务CronTriggerBean

    2.这里介绍第二种写法

    • 先创建一个普通的作业类,就是要执行自己业务的类
    • 配置spring 的配置文件

    普通作业类

      

    package com.sgfm.datacenter.action.quartz;
    
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.HashMap;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.apache.poi.util.SystemOutLogger;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Controller;
    
    import com.sgfm.base.action.BaseAction;
    import com.sgfm.base.util.AESUtil;
    import com.sgfm.datacenter.SysConstant;
    import com.sgfm.datacenter.entity.TMember;
    import com.sgfm.datacenter.exception.AppException;
    import com.sgfm.datacenter.service.health.RecordExplainService;
    import com.sgfm.datacenter.util.JsonResponseResult;
    import com.sgfm.datacenter.util.SysUtils;
    
    import net.sf.json.JSONObject;
    
    /*
     * 定时更新体检订单表的状态,在spring 配置文件托管bean
     */
    public class UpdOrderEndTimeAction extends BaseAction{
        private static final long serialVersionUID = 1L;
        private Log logger = LogFactory.getLog(this.getClass());
        
        @Autowired
        private RecordExplainService recordExplainService ; 
    
    
        //更新方法
        public String updateOrderInfo(){
            try{
                logger.info("开始执行定时任务");
                recordExplainService.updOrderState();
            }catch(AppException app){
                app.printStackTrace();
                logger.info("定时任务执行异常======UpdOrderEndTimeAction---->updateOrderInfo");
            }catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
                logger.info("时任务执行异常=======UpdOrderEndTimeAction---->updateOrderInfo");
                logger.info("");
            }
            return null;
        }

        //更新第二个表
            public void updateTjAndGjOrder(){
                try{
                    logger.info("开始执行定时任务2");
                }catch(AppException app){
                    app.printStackTrace();
                    logger.info("定时任务执行异常======UpdOrderEndTimeAction---->updateOrderInfo");
                }catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                    logger.info("定时任务执行异常=======UpdOrderEndTimeAction---->updateOrderInfo");
                    logger.info("");
                }
            }
    
    
    
    
    }

    spring 任务配置,要记得将quartz的相关jar包导入

    <?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:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
     xmlns:context="http://www.springframework.org/schema/context"
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
     default-lazy-init="false">
      
    <!--=========================================================写法1========================================================================--> <!-- task --> <!-- 定义了一个任务 --> <bean id="quartzClock" class="org.springframework.scheduling.quartz.JobDetailBean"> <property name="jobClass"> <value>com.sgfm.datacenter.quartz.DimingUpdateAllCache</value> </property> </bean> <bean id="quartzClock2" class="org.springframework.scheduling.quartz.JobDetailBean"> <property name="jobClass"> <value>com.sgfm.datacenter.quartz.DimingUpdateSectionCache</value> </property> </bean> <!-- 这种配置可以精确几点执行定时任务 --> <!-- 定义了任务的执行方式 --> <bean id="cronQuartzClock" class="org.springframework.scheduling.quartz.CronTriggerBean" > <property name="jobDetail"> <ref bean="quartzClock"></ref> </property> <property name="cronExpression"> <value>0 0 3 4/4 * ? </value> <!-- 服务启动之后,从第四天开始执行任务,之后每四天执行一次--> </property> </bean> <!-- 服务启动半小时秒之后运行 然后每一个小时执行一次任务 --> <bean id="quartzClockTask" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> <property name="jobDetail"> <ref bean="quartzClock2"/> </property> <property name="startDelay"><!--这里是服务启动后延时多少时间,开始计时任务,单位ms--> <value>3600000</value> </property> <property name="repeatInterval"><!--这里是每隔多长时间就进行一次计时任务,单位ms--> <value>3600000</value> </property> </bean> <!--第三步 启动定时任务,注意这里的ref bean --> <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="cronQuartzClock"></ref> <ref bean="quartzClockTask"></ref> </list> </property> </bean> <!-- ============================================================写法二 ============================================================--> <!-- 托管bean 默认单例模式 --> <bean id="UpOrderBean" class="com.sgfm.datacenter.action.quartz.UpdOrderEndTimeAction"/> <!-- 定义任务的执行方法 --> <bean id="upOrderTask" class= "org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ><ref bean="UpOrderBean"/></property> <property name="targetMethod" ><value>updateOrderInfo</value></property> <!-- false 表示非并发执行 --> <property name="concurrent" value =" false " /> </bean> <!-- 配置触发器,自定义触发时机 ,SimpleTriggerBean 每隔一段时间执行--> <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> <property name="jobDetail" ref="upOrderTask" /> <property name="startDelay" value="0" /><!-- 调度工厂实例化后,经过0秒开始执行调度 --> <property name="repeatInterval" value="300000" /><!-- 每5分钟调度一次 --> </bean>
         <!-- 任务描述2 --> 
         <bean id="upOrderTask2" class= "org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
             <property name="targetObject" ><ref bean="UpOrderBean"/></property>
             <property name="targetMethod" ><value>updateTjAndGjOrder</value></property>
            <!--  false 表示串行执行 -->
             <property name="concurrent" value =" false " />
          </bean>
       <bean id="simpleTrigger2" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
                  <property name="jobDetail" ref="upOrderTask2" />  
                <property name="startDelay" value="0" /><!-- 调度工厂实例化后,经过0秒开始执行调度  --> 
                 <property name="repeatInterval" value="300000" /><!-- 每5分钟调度一次 -->  
          </bean>
          <!-- 调度工厂 -->
       <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
            <property name="triggers">  
            <list>  
                <ref bean="simpleTrigger" />  
                <ref bean="simpleTrigger2" />  
            </list>  
            </property>  
    </bean> 
       
       
    </beans>

    方法2:定义了两个触发器,执行不同的方法。

    这里说一下concurrent 这个属性:

      1.场景:作业类A ,作业方法methodA(), 当作业A的bean 是一个无状态的bean 的时候,上一次执行A 的方法methodA的时间超过执行间隔时,下一次执行A的方法methodA又开始执行,这时候就会发生同一个作业的类的同一个方法并行执行。可能造成的后果是重复入库,数据库数据混乱。

      解决方式是:将concurrent=“false”  false 表示不允许并行执行,当上一次的任务执行完毕之后再执行下一次的任务

    300000
  • 相关阅读:
    javaScript面向对象继承方法经典实现
    javascript面向对象之Javascript 继承
    js面向对象 多种创建对象方法小结
    JavaScript 三种创建对象的方法
    正常上线的流程
    java.lang.NoClassDefFoundError: javax/servlet/ServletInputStream
    org/eclipse/jetty/util/component/Container$Listener
    java.io.IOException: Cannot find any registered HttpDestinationFactory from the Bus.
    java.lang.NoClassDefFoundError: javax/wsdl/extensions/ElementExtensible
    java.lang.ClassNotFoundException: org.objectweb.asm.ClassWriter
  • 原文地址:https://www.cnblogs.com/blogxiao/p/8145665.html
Copyright © 2011-2022 走看看