Spring整合Quartz任务调度

Quartz应用场景

1. 论坛每隔半个小时生成精华文章的RSS文件每天凌晨统计论坛用户的积分排名每隔30分钟执行锁定用户解锁任务

2. MIS系统在每月1号凌晨统计上个月各部门的业务数据生成月报表每半个小时查询用户是否已经有快到期的待处理业务

Quartz可见适合做定时任务。

这里使用的是Spring AOP进行日志管理案例,在开发中可能需要每个月自动创建日志表,并且创建的表结构和之前的日志表结构相同,这里就可以使用任务调度来创建石英调度。

Core表达式

1. Cron表达式的格式:秒分时日月周年(可选)。

字段名                允许的值                        允许的特殊字符  

秒                      0-59                               , - * /  

分                      0-59                               , - * /  

小时                    0-23                               , - * /  

日                     1-31                               , - * ? / L W C  

月                    1-12 or JAN-DEC                     , - * /  

周几                  1-7 or SUN-SAT                       , - * ? / L C #  

年 (可选字段)       empty, 1970-2099                         , - * /

"?"字符:表示不确定的值

","字符:指定数个值

"-"字符:指定一个值的范围

"/"字符:指定一个值的增加幅度。n/m表示从n开始,每次增加m

"L"字符:用在日表示一个月中的最后一天,用在周表示该月最后一个星期X

"W"字符:指定离给定日期最近的工作日(周一到周五)

#"字符:表示该月第几个周X。6#3表示该月第3个周五

 

"/":为特别单位,表示为"每"如"0/15"表示每隔15分钟执行一次,"0"表示为从"0"分开始, "3/20"表示表示每隔20分钟执行一次,"3"表示从第3分钟开始执行

"?":表示每月的某一天,或第周的某一天

"L":用于每月,或每周,表示为每月的最后一天,或每个月的最后星期几如"6L"表示"每月的最后一个星期五"

"W":表示为最近工作日,如"15W"放在每月(day-of-month)字段上表示为"到本月15日最近的工作日"

""#":是用来指定"的"每月第n个工作日,例在每周(day-of-week)这个字段中内容为"6#3" or "FRI#3" 则表示"每月第三个星期五"

2. Cron表达式范例:

每隔5秒执行一次:*/5 * * * * ?

每隔1分钟执行一次:0 */1 * * * ?

每天23点执行一次:0 0 23 * * ?

每天凌晨1点执行一次:0 0 1 * * ?

每月1号凌晨1点执行一次:0 0 1 1 * ?

每月最后一天23点执行一次:0 0 23 L * ?

每周星期天凌晨1点实行一次:0 0 1 ? * L

在26分、29分、33分执行一次:0 26,29,33 * * * ?

每天的0点、13点、18点、21点都执行一次:0 0 0,13,18,21 * * ?

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分每分触发

0 0/5 14 * * ? 每天下午的 2点到2点59分(整点开始,每隔5分触发)

0 0/5 14,18 * * ? 每天下午的 2点到2点59分(整点开始,每隔5分触发) 每天下午的 18点到18点59分(整点开始,每隔5分触发)

0 0-5 14 * * ? 每天下午的 2点到2点05分每分触发

0 10,44 14 ? 3 WED 3月分每周三下午的 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 每月的第三周的星期五开始触发

0 0 12 1/5 * ? 每月的第一个中午开始每隔5天触发一次

0 11 11 11 11 ? 每年的11月11号 11点11分触发(光棍节)

创建石英任务案例

1.引入quartz类库

com.springsource.org.quartz-1.6.2.jar

2.创建石英任务类[CreateTableTask.java]

package com.aaron.schedule; 

 

import java.util.HashMap; 

import java.util.List; 

import java.util.Map; 

 

import org.quartz.JobExecutionContext; 

import org.quartz.JobExecutionException; 

import org.springframework.beans.factory.annotation.Autowired; 

import org.springframework.scheduling.quartz.QuartzJobBean; 

 

import com.aaron.model.Users; 

import com.aaron.service.LogService; 

import com.aaron.util.LogUtil; 



/** 

 * @Author Aaron 

 * @Date 创建时间:2016-1-27 

 * @Version 1.0 

 * 

 * @Project_Package_Description springmvceasyuis || com.aaron.schedule 

 * @Function_Description 定时创建日志表任务

* 

 */ 

public class CreateTableTask extends QuartzJobBean { 

    @Autowired 

    LogService logService; 

    //注入LogService 

    public void setLogService(LogService logService) { 

        this.logService = logService; 

    } 

    /** 

     * 定时生成日志表

     */ 

    @Override 

    protected void executeInternal(JobExecutionContext arg0) 

            throws JobExecutionException { 

        Map<String, Object> map=new HashMap<String, Object>(); 

        System.out.println("开始建表》》》》》》》》》"); 

        //下一月

        String tablename = LogUtil.generateLogTableName(1); 

        String sql = "create table if not exists "+tablename+" like tb_log"; 

        System.out.println("下一月:建表sql》》》》》"+sql); 

        map.put("sql", sql); 

        logService.createTable(map); 

         

        //下两月

        tablename = LogUtil.generateLogTableName(2); 

        sql = "create table if not exists "+tablename+" like tb_log"; 

        System.out.println("下两月:建表sql》》》》》"+sql); 

        map.put("sql", sql); 

        logService.createTable(map); 

        System.out.println("建表完成"); 

    } 

} 

 

3.配置调度任务 [schedules.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" 

    xsi:schemaLocation="http://www.springframework.org/schema/beans  

                        http://www.springframework.org/schema/beans/spring-beans.xsd"> 

    <!-- 任务明细bean --> 

    <bean id="jobDetailBean" class="org.springframework.scheduling.quartz.JobDetailBean"> 

        <!-- 通过任务类指定石英任务 --> 

        <property name="jobClass" value="com.aaron.schedule.CreateTableTask" /> 

        <property name="jobDataMap"> 

            <map> 

                <entry key="logService" value-ref="logService" /> 

            </map> 

        </property> 

    </bean> 

    <!-- cron触发器bean,设置石英任务的调度策略 -->

    <bean id="cronTriggerBean" class="org.springframework.scheduling.quartz.CronTriggerBean"> 

        <property name="jobDetail" ref="jobDetailBean" /> 

        <!-- cron表达式 --> 

        <property name="cronExpression"> 

            <!-- 每天12点触发 -->

            <!-- <value>0 0 12 * * ?</value> --> 

             <!-- 每月15号上午10点15分触发 -->

             <!-- <value>0 15 10 15 * ?</value> --> 

             <!-- 每两秒执行一次 --> 

             <!-- <value>0/2 * * * * ?</value> --> 

             <!-- 每一分钟执行一次 --> 

             <value>0 */1 * * * ?</value> 

        </property> 

    </bean> 


    <!-- 调度工厂bean,激活触发器运行 -->

    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> 

        <property name="triggers"> 

            <list> 

                <ref bean="cronTriggerBean"/> 

            </list> 

        </property> 

    </bean> 

</beans> 

 

4.配置web.xml文件,一同加载spring的所有配置文件

 

<context-param> 

        <param-name>contextConfigLocation</param-name> 

        <param-value> 

            classpath:spring-bean.xml,classpath:schedules.xml 

        </param-value> 

</context-param> 

 

补充:这里使用的是mybatis做ORM框架,在创建石英任务类[CreateTableTask.java]时,开始是将表名当做参数传过去

map.put("tablename", tablename); 

logService.createTable(map); 
<insert id="createTable" parameterType="java.util.Map"> 

        create table if not exists #{tablename} like tb_log 

</insert> 

后台一直报错,创建不了表名。后来在网上查到"Mybatis动态创建表"这个问题,解决的方法就是直接将整个sql封装到map中传过去

String sql = "create table if not exists "+tablename+" like tb_log"; 

map.put("sql", sql); 

logService.createTable(map); 

 

<insert id="createTable" parameterType="java.util.Map"> 

   ${sql} 

</insert> 

 

 

posted @ 2016-01-27 10:43  Aaron殇醉月  阅读(468)  评论(0编辑  收藏  举报