Spring 整合 Quartz 任务调度框架学习笔记

原创 2015年11月08日 04:58:54

Spring 整合 Quartz 任务调度框架学习笔记

参考资料:
(1)Spring整合Quartz(JobDetailBean方式) - Java编程思想的个人空间 - 开源中国社区 http://my.oschina.net/u/1157906/blog/193612
(2)Spring中Quartz的配置 - 樊凯 - 博客园 http://www.cnblogs.com/kay/archive/2007/11/02/947372.html
(3)定时器(Quartz)快速入门 - Barudisshu的个人空间 - 开源中国社区 http://my.oschina.net/Barudisshu/blog/294272
(4)job用法 JobDetailBean_小组_ThinkSAAS http://www.thinksaas.cn/group/topic/235247/
(5)参考资料:
http://www.mkyong.com/spring-batch/spring-batch-and-quartz-scheduler-example/
(6)Corn 表达式 - Rain520 - 博客园 http://www.cnblogs.com/ycdx2001/p/4876210.html

其实在 Java 中有一个 Java 类,名叫 Timer,可以帮助我们实现周期性地执行某段代码。下面,我们看一个例子:

public class TimerTest {

    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

    @Test
    public static void main(String[] args) {
        Timer time = new Timer();
        time.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("周期性执行。。。 " + sdf.format(new Date()));
            }
        },1*1000,3*1000);
    }

}

在 Spring 中使用 Quartz 有两种方式实现:第一种是任务类继承 QuartzJobBean ,第二种则是在配置文件里定义任务类和要执行的方法,类和方法仍然是普通类。很显然,第二种方式远比第一种方式来的灵活。 我们首先介绍第二种方式。

一、使用 Spring4 集成 Quartz 2.2.2 的情况(最佳实践)

引入依赖:

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.2</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>${spring.version}</version>
</dependency>

1、配置 job 工作类,工作类里定义了要周期性执行的方法,在配置中通过 MethodInvokingJobDetailFactoryBean 体现;

<!-- job 的配置开始 -->
<!-- 定义调用的对象和调用对象的方法 -->
<bean id="jobtask" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    <!-- 调用的类(指定包含任务执行体的 Bean 实例) -->
    <property name="targetObject">
        <ref bean="quartzJob" />
    </property>

    <!-- 调用类中的方法(将指定 Bean 实例的某个特定方法包装成任务的执行体) -->
    <property name="targetMethod">
        <value>work</value>
    </property>
</bean>
<!-- job 的配置结束 -->

2、配置触发器,定义了周期性执行的任务如何触发

Quartz 中提供了两种触发器,分别是 CronTriggerSimpleTrigger
(1)SimpleTrigger
每隔若干毫秒来触发纳入进度的任务。因此,对于夏令时来说,根本不需要做任何特殊的处理来“保持进度”。它只是简单地保持每隔若干毫秒来触发一次,无论你的 SimpleTrigger每隔10秒触发一次还是每隔15分钟触发一次,还是每隔24小时触发一次。
示例代码:

<!-- 创建一个触发器 -->
<bean id="simpleTrigger"
      class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
   <property name="jobDetail" ref="weixinJob" />
   <property name="repeatInterval" value="2000" /><!-- 6000000 ,表示 6000 秒-->
   <property name="startDelay" value="1000" />
</bean>

(2)CronTrigger
在特定“格林日历”时刻触发纳入进程的任务,因此,如果创建一个在每天上午10点触发的触发器,那么,在夏令时执行之前,系统将继续如此运作。但是,取决于是春季还是秋季夏令时,因为对于特定的星期日,从星期六上午10点到星期日上午10点之间的时间间隔将不是24小时,而可能是23或者25个小时。
示例代码:

<!-- 调度的配置开始 -->
<!-- 定义触发时间 -->
<bean id="doTime" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
    <property name="jobDetail">
        <ref bean="jobtask" />
    </property>

    <!-- cron 表达式 -->
    <property name="cronExpression">
        <value>*/3 * * * * ?</value><!-- 每隔 3 秒执行一次 -->
    </property>
</bean>
<!-- 调度的配置结束 -->

总之,如果你记住下面的两条规则,则会感觉良好并且很容易记忆:
• SimpleTrigger 总是每隔若干秒触发,而同夏令时没有关系。
• CronTrigger 总是在给定的时间出发然后计算它下次触发的时间。如果在给定的日期内没有该时间,则触发器将会被忽略,如果在给定的日期内该时间发生了两次,它只触发一次。因为是在第一次触发发生后计算当天下次触发的时间。

3、配置启动触发器

<!-- 启动触发器的配置开始 -->
<!-- 总管理类 -->
<!-- lazy-init="false" 表示容器启动的时候就会执行调度程序 -->
<bean id="startQuartz" lazy-init="false" autowire="no"
    class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
        <list>
            <ref bean="doTime" />
        </list>
    </property>
</bean>
<!-- 启动触发器的配置结束 -->

二、使用 Spring3 集成 Quartz 1.8 的情况(使用继承 QuartzJobBean 的方式,不是最佳实践)

1、引入依赖

compile 'org.quartz-scheduler:quartz:1.8.6'
compile 'org.springframework:spring-core:3.2.2.RELEASE'
compile 'org.springframework:spring-tx:3.2.2.RELEASE'
compile 'org.springframework:spring-context-support:3.2.2.RELEASE'

2、编写服务层

public class RefreshTokenService {
    public String refreshToken(){
        return "111111222222333333";
    }
}

3、编写 Job

注意:这里要继承 QuartzJobBean ,实现 executeInternal(JobExecutionContext jobExecutionContext) 方法,该方法里的代码就是我们周期性执行的任务调度的代码。

public class WeixinQuartzJob extends QuartzJobBean {

    private RefreshTokenService refreshTokenService;

    public void setRefreshTokenService(RefreshTokenService refreshTokenService) {
        this.refreshTokenService = refreshTokenService;
    }

    /**
     * 该方法体里面就是定期执行的任务调度
     * @param jobExecutionContext
     */
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext){
        System.out.println(refreshTokenService.refreshToken() + " " + getCurrentTime());
    }

    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

    private String getCurrentTime(){
        return sdf.format(new Date());
    }

}

4、在 Spring 的核心配置文件里进行相关配置

(1)定义 JobDetailBean

<bean id="refreshAccessTokenJob"
          class="org.springframework.scheduling.quartz.JobDetailBean">
    <!-- 定义 Job 的 Bean -->
    <property name="jobClass">
        <value>
            com.liwei.schedule.WeixinQuartzJob
        </value>
    </property>

    <!-- 定义 Job 的 Bean 中引用到的其他 Bean -->
    <property name="jobDataAsMap">
        <map>
            <entry key="refreshTokenService">
                <ref bean="refreshAccessTokenTask" />
            </entry>
        </map>
    </property>
</bean>

其中,refreshAccessTokenTask 是我们定义的一个 bean 的 id。

<bean id="refreshAccessTokenTask" class="com.liwei.service.RefreshTokenService"></bean>

(2)定义简单触发器

<bean id="refreshAccessTokenTrigger"
      class="org.springframework.scheduling.quartz.SimpleTriggerBean">
    <property name="jobDetail" ref="refreshAccessTokenJob" />
    <property name="repeatInterval" value="3000" />
    <property name="startDelay" value="1000" />
</bean>

说明:我们的触发器还可以是 cron 表达式,例如:

<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
    <property name="jobDetail" ref="runMeJob" />
    <property name="cronExpression" value="0/5 * * * * ?" />
</bean>

(3)定义计划任务调度工厂 SchedulerFactoryBean

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
   <property name="jobDetails">
       <list>
           <ref bean="refreshAccessTokenJob" />
       </list>
   </property>
   <property name="triggers">
       <list>
           <ref bean="refreshAccessTokenTrigger" />
       </list>
   </property>
</bean>

5、编写测试类

public class QuartzTest {

    private static AbstractApplicationContext ctx;

    /**
     * 用 junit 的 test 方法看不到周期执行的效果,
     * 一定要用原始的 main 方法才能看到周期执行的效果
     */
    @Test
    public void test01(){
        try {
            Thread.sleep(15*1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        ctx = new ClassPathXmlApplicationContext("beans.xml");

    }
}

Spring整合定时任务调度框架Quartz实战

定时的任务处理在程序开发中应用的相当普遍,之前一直使用JDK的Timer类库来做任务调度功能不是很方便,因为它不能像cron服务那样可以指定具体年、月、日、时和分的时间,我们只能将时间通过换算成微秒后...
  • a1314517love
  • a1314517love
  • 2014年09月12日 11:51
  • 11688

搭建批处理框架问题总结Spring Batch + Spring Batch Admin + Quartz

Transaction Manager 事务管理器问题: 问题现象:在Tasklet中调用Dao  update更新数据,发现数据库没有变。 问题分析:猜测是没有commit 原来,我用了spr...
  • qq_15955643
  • qq_15955643
  • 2015年07月06日 16:43
  • 1605

项目开发(包含webService、springbatch、quartz等)

  • 2017年07月24日 16:48
  • 4.76MB
  • 下载

spring boot + spring batch+ quartz实例

注:本文非基础教学类文章 首先工程用到的主要jar包 spring-batch-core-3.0.0.jar quartz-2.1.6.jar (一) quartz实现  实际开发...
  • u013109657
  • u013109657
  • 2017年08月23日 16:39
  • 1767

Spring整理系列(09)——spring与quartz整合触发器执行表达式cronExpression详解

CronTriggers往往比SimpleTrigger更有用,如果您需要基于日历的概念,而非SimpleTrigger完全指定的时间间隔,复发的发射工作的时间表。 CronTrigger,你可以指...
  • javaloveiphone
  • javaloveiphone
  • 2016年08月09日 18:02
  • 989

spring-batch+quartz的示例

spring-batch是一个为批量处理面生的轻量级框架,关于它的描述不多说了,网上挺多的。下面要说的是一个spring-batch+quartz的一示例,完成的功能是从mysql中定时取数据,然后处...
  • riapgypm
  • riapgypm
  • 2016年01月14日 16:31
  • 7351

Spring框架中的Quartz学习使用

Spring框架中的Quartz使用: 首先简单介绍下Quartz,它是一个完全由Java编写的开源作业调度框架,为在Java应用程序中进行作业调度提供了简单却强大的机制,相当于java.util.T...
  • JY_He
  • JY_He
  • 2016年08月13日 14:00
  • 2275

Spring配置Quartz任务调度框架教程

上篇博客讲解了Quartz中核心概念,以及在J2SE中使用。  这篇博客开始介绍,在J2EE中Spring与Quartz的配置使用。  在操作时,注意版本问题,上篇博客也提到,Quartz...
  • llhhyy1989
  • llhhyy1989
  • 2013年06月07日 17:08
  • 5348

Java任务调度框架Quartz教程实例

介绍  Quartz is a full-featured, open source job scheduling service that can be integrated with, or u...
  • llhhyy1989
  • llhhyy1989
  • 2013年06月07日 11:01
  • 61568

Quartz任务调度框架

Quartz 任务调度框架
  • Scplove
  • Scplove
  • 2016年08月19日 17:07
  • 6445
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Spring 整合 Quartz 任务调度框架学习笔记
举报原因:
原因补充:

(最多只允许输入30个字)