Quartz 入门

简介

可以用来创建执行数十,数百乃至数万个作业的简单或复杂的计划;开源的完全使用JAVA开发的一种时间调度框架,可多线程同步执行。支持集群、JTA事务(听着好高大上,说白了就是定时器~,与以往不同的是,他支持大量的定时任务同步执行,还可以将定时信息保存到数据库中在需要的时候在开启执行,可以防止数据丢失,也可以随时查看定时任务的信息)

使用

quartz 下载地址: http://www.quartz-scheduler.org/downloads/ 

quartz有两种使用方式:RAM、JDBC。任务的调度也有两种方式:SimpleSchedule、CronSchedule

RAM方式:

程序直接运行在内存中

1、导入 Quartz 的jar包,官网有zip文件可供下载,maven 项目则需要导入依赖

    <!-- quartz begin -->
      <dependency>
       <groupId>org.quartz-scheduler</groupId>
       <artifactId>quartz</artifactId>
       <version>2.2.1</version>
     </dependency>
     <dependency>
       <groupId>org.quartz-scheduler</groupId>
       <artifactId>quartz-jobs</artifactId>
       <version>2.2.1</version>
     </dependency> 
     <!-- quartz end -->
     
     <!-- log -->
     <dependency>  
        <groupId>org.slf4j</groupId>  
        <artifactId>slf4j-simple</artifactId>  
        <version>1.7.25</version>  
    </dependency>

2、创建 quartz.properties  文件放到 classpath 中

#JDBC驱动
#org.quartz.dataSource.qzDS.driver:com.mysql.jdbc.Driver
#org.quartz.dataSource.qzDS.URL:jdbc:mysql://localhost:3306/test
#org.quartz.dataSource.qzDS.user:root
#org.quartz.dataSource.qzDS.password:
#org.quartz.dataSource.qzDS.maxConnection:10

org.quartz.scheduler.instanceName=MyScheduler
org.quartz.threadPool.threadCount=3
org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore

3、创建具体的任务

package com.quartz.first;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class MyJob implements Job {

    private static final String NAME = "name";
    
    @Override
    public void execute(JobExecutionContext arg0) throws JobExecutionException {
        
        System.out.println(" execute job() ...  ");
    }

}

调用

package com.quartz.first;

import java.util.Date;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

/**
 * 
 * 使用 RAM 方式定时
 * 
 * @author 丰志
 *
 */
public class RAMQuartz {

    public static void main(String[] args) throws SchedulerException {
        //1.创建Scheduler的工厂
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        //2.从工厂中获取调度器实例
        Scheduler scheduler = schedulerFactory.getScheduler();
        //3.创建JobDetail
        JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
                .withDescription("this is a ram job") //job的描述
                .withIdentity("ramJob", "ramGroup") //job 的name和group
                .build();

//        jobDetail.getJobDataMap().put("name", "zhangsan"); //传参用与MyJob中获取参数    jobDataMap.get("name")
        
        //任务运行的时间,SimpleSchedle类型触发器有效
        long time=  System.currentTimeMillis() + 3*1000L; //3秒后启动任务
        Date statTime = new Date(time);

        //4.创建Trigger
        //使用SimpleScheduleBuilder或者CronScheduleBuilder
        Trigger trigger = TriggerBuilder.newTrigger()
                    .withDescription("")
                    .withIdentity("ramTrigger", "ramTriggerGroup")
                    .startAt(statTime)  //默认当前时间启动
//                    .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).withRepeatCount(10)) // 每个2秒钟执行一次,一共执行10次
//                    .withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?")) //两秒执行一次,cron 秒、分、时、日、月、年、
                    .build();

        //5.注册任务和定时器
        scheduler.scheduleJob(jobDetail, trigger);
        //6.启动 调度器
        scheduler.start();
    }
}

 结果:

到此就实现了基本的调度任务,但是在实际项目中往往需要用到quartz跟一些开发框架的集成

spring集成quartz

   使用spring框架来管理quartz可以使开发变得简单,只需要书写具体的任务即可,因为不在需要写JAVA代码来开启任务,spring会根据配置文件中的配置自动开启省去了手写的调度过程。具体实现:

1、添加 spring 支持(添加之前的依赖):

<dependency>                                
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>${spring.version}</version>
</dependency>

2、创建具体的任务

Simple方式:

package org.quartz.demo;

import java.util.Date;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

public class SimpleJob extends QuartzJobBean {

    @Override
    protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException {
        System.out.println("------   执行ExampleJob     -------"  + new Date());
    }
}

Cron方式:

package org.quartz.demo;

import java.util.Date;

public class CronJob {

    public void doIt() {
        System.out.println("======    执行 ExampleBusinessObject.doIt...       ======" + new Date());
    }
}

3、配置 spring-quartz.xml 文件:

spring 的applicationContext.xml文件中添加quartz:

<import resource="classpath:conf/spring-quartz.xml" />

配置 spring-quartz.xml

Simple方式:

<?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:aop="http://www.springframework.org/schema/aop"
    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-3.2.xsd
   http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
    
    <!-- 具体执行的任务 --> 
    <bean name="simpleJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <property name="jobClass" value="org.quartz.demo.SimpleJob"/>
    </bean>
    
    <!-- Simple触发器 -->    
    <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
        <property name="jobDetail" ref="simpleJob"/>
        <property name="startDelay" value="50000"/>
        <property name="repeatInterval" value="5000"/>
    </bean>  
     
    <!-- 调度工厂 --> 
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
                <ref bean="simpleTrigger"/>
            </list>
        </property>
    </bean>
    
</beans>

Cron方式:

<?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:aop="http://www.springframework.org/schema/aop"
    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-3.2.xsd
   http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
    
    <!-- 具体的任务 -->
    <bean id="cronJob" class="org.quartz.demo.CronJob"/>
    
    <!-- JobDetail -->
    <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="cronJob"/>
        <property name="targetMethod" value="doIt"/>
    </bean>
    
    <!-- Cron触发器 -->
    <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="jobDetail"/>
        <property name="cronExpression" value="10 * * * * ?"/> 
    </bean>  
     
    <!-- 调度工厂 --> 
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
                <ref bean="cronTrigger"/>
            </list>
        </property>
    </bean>
    
</beans>

启动 tomcat 测试结果

Cron.doIt 每分钟的第 10 秒执行一次, SimpleJob 每 5 秒钟执行一次。两个任务可以同时调度。测试通过~

JDBC方式:

如果需要使用 JDBC模式需要下载官方的资料,进入 quartz-2.2.3 / docs / dbTables 里面有所有的 sql 文件,可以执行具体的 sql 生成需要的数据表,数据表只有在使用 JDBC 模式的情况下才有效,这里只是初步的记录下quartz的使用。

1、根据官方文档提供的 sql 生成相应的数据表

在下载文件夹下进入 quartz-2.2.3 / docs / dbTables 执行相应的 sql 生成对应的数据表

其中常用的

  qrtz_cron_tiggers:  记录使用 CRON 表达式定义的触发器

  qrtz_fired_triggers:  记录触发器的执行时间

  qrtz_job_details:  记录具体任务的名称,组,类名等信息

  qrtz_simple_triggers:  记录使用 Simple 方式定义的触发器

  qrtz_triggers:  记录触发器执行的详细信息,包括任务的名称、组,触发器的名称、组以及触发器的开始执行时间、上次执行的时间和下一次执行的时间等信息

2、配置 quartz.properties 放到 classpath 目录下

org.quartz.threadPool.threadCount=3
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.dataSource = myDS

org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost:3306/test
org.quartz.dataSource.myDS.user = root
org.quartz.dataSource.myDS.password =
org.quartz.dataSource.myDS.maxConnections = 30

在这儿只列举基本的配置,详细的参考:  http://www.quartz-scheduler.org/documentation/quartz-2.1.x/configuration/ 

3、配置具体的任务

package com.quartz.first;

import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class MyJob implements Job {

    private static final String NAME = "name";
    
    @Override
    public void execute(JobExecutionContext arg0) throws JobExecutionException {
        
        System.out.println(" execute jdbcJob() ...  ");
    }

}

4、调用测试

package com.quartz.first;

import java.util.List;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

public class JDBCQuartz {

    public static void main(String[] args) throws SchedulerException {
        
        startSchedule(); //开始执行定时任务,同时会向数据库写入任务、触发器、调度等数据
        //resumeJob(); // 重新执行
    }

    private static void startSchedule() {
        try {
            // 1、创建JobDetail实例
            JobDetail jobDetail = JobBuilder.newJob(MyJob.class).withIdentity("job1", "group1").build();

            // 2、设置触发器类型 、执行次数
//            SimpleScheduleBuilder simpleScheduleBuilder = SimpleScheduleBuilder.repeatSecondlyForTotalCount(5);
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/2 * * * * ?");

            // 3、创建Trigger
            Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow()
                    .withSchedule(cronScheduleBuilder).build();

            // 4、创建Scheduler
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
            scheduler.start();

            // 5、调度执行
            scheduler.scheduleJob(jobDetail, trigger);
            try {
                Thread.sleep(60000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            // 关闭调度器
            // scheduler.shutdown();

        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    /** 从数据库中找到已经存在的job,并重新开户调度 */
    private static void resumeJob() {
        try {

            SchedulerFactory schedulerFactory = new StdSchedulerFactory();
            Scheduler scheduler = schedulerFactory.getScheduler();
            JobKey jobKey = new JobKey("job1", "group1");
            List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
            if (triggers.size() > 0) {
                for (Trigger tg : triggers) {
                    // 根据类型判断
                    if ((tg instanceof CronTrigger) || (tg instanceof SimpleTrigger)) {
                        // 恢复job运行
                        scheduler.resumeJob(jobKey);
                    }
                }
                scheduler.start();
            }

        } catch (Exception e) {
            e.printStackTrace();

        }
    }
}

运行结果:

数据库:

 

 

关闭服务,执行修改代码执行resumeJob():  

一秒钟执行了这么多次,调用成功。

到此基本的使用应该没什么问题了   (~ ̄▽ ̄ ~)

源码: https://files.cnblogs.com/files/guofz/myFirstQuartz.rar

Quartz官方介绍:  http://www.quartz-scheduler.org/documentation/quartz-2.2.x/quick-start.html

Spring官方文档介绍集成 Quartz 地址:https://docs.spring.io/spring/docs/4.3.17.BUILD-SNAPSHOT/spring-framework-reference/htmlsingle/

最后:欢迎吐槽指正~ 

 

posted @ 2018-04-27 16:58  五毒不侵滴bug  阅读(322)  评论(1编辑  收藏  举报