轻松搞定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
原文地址:https://www.cnblogs.com/blogxiao/p/8145665.html