使用spring+quartz配置多个定时任务

首先引入 quartz jar包;

创建java类:

package com.tcwl.vsmp.loanmgt.message;

import com.tcwl.vsmp.external.constant.SmsConstant;
import com.tcwl.vsmp.external.service.sms.SmsProxy;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * Project Name: 
 * FileName: SMSScheduler
 * Author:    苏凯
 * Date:     2018/8/30 15:27
 * Description: 定时短信发送
 *
 * @version 1.0.0
 * @since: 1.0.0
 * Copyright (C), 2015-2018, 
 */
@Configurable
public class SMSScheduler {




   /**
     * 提醒客户还款
     */
    public void sendMessageForClientWithRepayment() {
        System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " -> Hello, 我是任务 1");
        int day = 0;
        int days = 0;
        // TIMEDPUSHDAY 为配置文件中所配置的天数;查询在这个天数范围内的数据
        if (null != TIMEDPUSHDAY) {
            day = Integer.parseInt(TIMEDPUSHDAY);
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss ");
            Date date1 = null;
            String format1 = "";
            Date date2 = null;
            String format2 = "";
            for (int i = 0; i < day + 1; i++) {
                days = day - 1;
                Calendar time1 = Calendar.getInstance();
                Calendar time2 = Calendar.getInstance();
                days = days - i;
                //获取当天的时间范围
                //  REPAY_DEADLINE 为配置文件中所配置的还款期限;一般为45天
                time(days, time1, time2, REPAY_DEADLINE);
                date1 = time1.getTime();
                format1 = df.format(date1);
                date2 = time2.getTime();
                format2 = df.format(date2);
                if (i < day) {

                    String message = "距离还款日期天数:" + (day - i) + "日,";
                    List<LoanTable> loanTables = 
                             service.queryRefundTimeBorrowerInfo(format1, format2
                            , LoanConstant.LOAN_STATUS_HAS_APPROVE
                            , LoanConstant.LOAN_STATUS_WILL_EXPIRE
                            , LoanConstant.LOAN_STATUS_OVER_DUE);
                    //给即将到期的客户发送短信
                    sendMessageOverdue(message, loanTables);
                } else if (i == day) {

                    List<LoanTable> loanTables = 
                            service.queryRefundTimeBorrowerInfo2(format1
                            , LoanConstant.LOAN_STATUS_HAS_APPROVE
                            , LoanConstant.LOAN_STATUS_WILL_EXPIRE
                            , LoanConstant.LOAN_STATUS_OVER_DUE);
                    String message = "已逾期;";
                    //给逾期客户发短信
                    sendMessageOverdue(message, loanTables);
                }
            }
        }

    }


   /**
     * @param message
     * @param loanTables 提醒客户还款
     *                   给即将到期的客户发送短信、给逾期客户发短信
     */
    private void sendMessageOverdue(String message, List<LoanTable> loanTables) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar now = Calendar.getInstance();
        Date date1 = null;
        //逾期时间
        String borrowSuccessTime = "";
        if (null != loanTables && 0 < loanTables.size()) {
            for (int j = 0; j < loanTables.size(); j++) {
                //客户手机号
                String tel = loanTables.get(j).getBorrower_tel() != null ? 
                             loanTables.get(j).getBorrower_tel() : "";
                //客户名
                String name = loanTables.get(j).getBorrower_name() != null ? 
                              loanTables.get(j).getBorrower_name() : "";
                //还款日期
                String refund_time = loanTables.get(j).getRefund_time() != null ? 
                                     loanTables.get(j).getRefund_time() : "";
                //还款金额
                Double amount = loanTables.get(j).getAmount() != null ? 
                                loanTables.get(j).getAmount() : 0.0;
                //借款时间
                String borrow_success_time = loanTables.get(j).getBorrow_success_time() 
                                             != null ? 
                                             loanTables.get(j).getBorrow_success_time() : 
                                             "";

                //计算逾期时间
                borrowSuccessTime = getoverdueTime(df, now, borrow_success_time);

             /*   System.out.println((tel + "," + name + "先生/女士,您好!"
                        + "您的借款金额期到期时间:" + borrowSuccessTime + ", 还款金额:" + 
                        amount
                        + "元," + message + "欢迎您使用XXX,祝您体验愉快!【XXX】"));*/
                try {
                    //打开注释,恢复短信功能;
                    /*SmsProxy.sendSms(tel, name + "先生/女士,您好!"
                                    + "您的借款金额期到期时间:" +refund_time+", 还款金额:" 
                                    + amount
                                    + "元,"+message+"欢迎您使用XXXX,祝您体验愉快! 
                                    【XXX】", 1,
                            SmsConstant.SMS_CHANNEL_JIANZHOU_NO_EXAMINE);*/
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }
    }

  /**
     * 获取当天的时间范围
     *
     * @param days
     * @param time1
     * @param time2 定时推送还款信息包括截止还款日期,距离还款日期天数,
     *              到期还款金额,逾期提醒根据借口数据短信或推送通知客户
     */
    private void time(int days, Calendar time1, Calendar time2, Integer REPAY_DEADLINE) {
        time1.add(Calendar.DATE, (-REPAY_DEADLINE + days));
        // 时
        time1.set(Calendar.HOUR_OF_DAY, 0);
        // 分
        time1.set(Calendar.MINUTE, 0);
        // 秒
        time1.set(Calendar.SECOND, 0);
        // 毫秒
        time1.set(Calendar.MILLISECOND, 0);
        time2.add(Calendar.DATE, (-REPAY_DEADLINE + days));
        // 时
        time2.set(Calendar.HOUR_OF_DAY, 23);
        // 分
        time2.set(Calendar.MINUTE, 59);
        // 秒
        time2.set(Calendar.SECOND, 59);
        // 毫秒
        time2.set(Calendar.MILLISECOND, 0);
    }

/**
     * @param now                 当前时间
     * @param borrow_success_time 借款通过时间
     * @return 还款截止时间
     * 计算逾期时间
     * SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
     * Calendar now = Calendar.getInstance();
     */
    private String getoverdueTime(SimpleDateFormat df, Calendar now, String borrow_success_time) {
        String borrowSuccessTime = "";
        Date date1;//计算逾期时间
        if (null != borrow_success_time && 0 < borrow_success_time.length()) {
            // 表达式对象
            Pattern p = Pattern.compile("^[1-9]\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])" +
                    "\\s+(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d$");
            // 创建 Matcher 对象
            Matcher m = p.matcher(borrow_success_time);
            // 是否完全匹配
            if (m.matches()) {
                try {
                    Date parse = df.parse(borrow_success_time);
                    now.setTime(parse);
                    //加上到期天数
                    now.add(Calendar.DATE, REPAY_DEADLINE);
                    date1 = now.getTime();
                    borrowSuccessTime = df.format(date1);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return borrowSuccessTime;
    }
}

配置定时器 spring-quartz.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans.xsd">   
 <!-- 调度器 触发器-->
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
             <!--   <ref bean="myTrigger"/>
                <ref bean="loanExpireSmsTrigger"/>
                <ref bean="expandSearchTrigger"/>
                <ref bean="zshChargeApplyRecordTrigger"/>
                <ref bean="LoanSmsRemindQuartzTrigger"/>
                <ref bean="ZshWalletQuartzTrigger"/>
                <ref bean="ZshGetFileQuartzTrigger"/>
                <ref bean="downloadConsumeFileTrigger"/> 可以配多个任务 -->

                <ref bean="cronTrigger_1" />
                <ref bean="cronTrigger_2" />
            </list>
        </property>
    </bean>

    <!-- 定时任务配置 1-->
   <bean name="SMSScheduler" class="com.tcwl.vsmp.loanmgt.message.SMSScheduler"/>
    <bean id="SMSSDetail_1" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject">
            <ref bean="SMSScheduler" />
        </property>
        <property name="targetMethod">
            <value>sendMessage</value>
        </property>
    </bean>
    <bean id="cronTrigger_1" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <property name="jobDetail">
            <ref bean="SMSSDetail_1" />
        </property>
        <!-- 每一秒钟执行一次 -->
        <property name="cronExpression">
            <value>0/1 * * * * ?</value>
        </property>
    </bean>

<!-- 定时任务配置 2-->
<!--短信通知金鑫逾期的客户名单与已经逾期的客户名单-->
    <bean id="SMSSDetail_2" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject">
            <ref bean="SMSScheduler" />
        </property>
        <property name="targetMethod">
            <value>sendMessageJinXinWithRepayment</value>
        </property>
    </bean>
    <bean id="cronTrigger_2" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <property name="jobDetail">
            <ref bean="SMSSDetail_2" />
        </property>
        <!-- 定N 时间执行一次 -->
        <property name="cronExpression">
            <!-- 读配置文件中的时间 -->
            <value>#{prop.SMSSCHEDUlER_JINXING_TIME}</value>
        </property>
    </bean>

web.xml加载定时配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	version="3.0">
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<context-param>
		<param-name>contextConfigLocation</param-name>
        <param-value> 
        /WEB-INF/classes/spring-quartz.xml
        </param-value>
	</context-param>

配置文件:

conf/SMSScheduler.properties

#---------------------客户-----------------------------
#定时推送还款信息;截止还款日期前第N天开始推送信息;
TIMEDPUSHDAY = 3
#定时推送还款信息;发送客户时间设定;
SMSSCHEDUlERTIME = 0/20 * * * * ?
#---------------------金鑫-----------------------------
#定时推送还款信息;推送资方手机号配置;
SMSSCHEDUlER_JINXING_IPHONENUM = 18********
#定时推送还款信息;发送时间设定;
SMSSCHEDUlER_JINXING_TIME = 0/20 * * * * ?
#---------------------财务-----------------------------
#还款短信通知财务;手机号
SMSSCHEDUlER_CANWUBU_IPHONENUM = 18********

加载 conf/SMSScheduler.properties 配置文件:

applicationContext.xml

	<bean id="prop" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
	<property name="locations">
 		<array>
 			<value>classpath:conf/*</value>
 		</array>
 	</property>
	<property name="fileEncoding" value="UTF-8"/>
 </bean>

时间计算:cron

可以去这个网站 http://cron.qqe2.com/

下面这张图选择的是每天上午2点发送短信,可参照:

注意:

Spring被用在了越来越多的项目中, quartz也被公认为是比较好用的定时器设置工具, 在这里通过一个demo说明如何使用spring和quartz配置多个定时任务.

环境: eclipse + maven + spring 3.0.6.RELEASE版本 + quartz 1.8.6版本

需要引入的jar包, 这里是采用maven的dependency依赖; 如果没有使用maven, 可以对照着上面的jar包截图一一进行下载. 这里唯一需要注意的就是, 如果使用spring 3.1以下的版本, quartz就需要相应的2.0以下版本, 否则会导致 org.springframework.beans.factory.CannotLoadBeanClassException: Error loading class [org.springframework.scheduling.quartz.CronTriggerBean] for bean with name 'cronTrigger_1' defined in file [E:\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\git-common\WEB-INF\classes\applicationContext.xml]: problem with class file or dependent class; nested exception isjava.lang.IncompatibleClassChangeError: class org.springframework.scheduling.quartz.CronTriggerBean has interface org.quartz.CronTrigger as super class 错误.

后续: 后来使用了spring 4.0.5.RELEASE版本+quartz 2.2.1版本, 还是报出了以上错误, 将quartz降低为1.8.6版本后, 问题消失...

猜你喜欢

转载自blog.csdn.net/qq_15204179/article/details/82223246