Quartz简介

Quartz是Job Scheduling(任务调度)领域的开源项目,可单独使用,也可和JavaSE,EE进行组合,是一个任务调度管理系统,可在特定的时间内执行特定的任务,如想在Java中使用Quartz,则只需将Quartz的jar包导入到项目中即可.

Quartz相关介绍

Jobs:任务

是实际想要执行的操作,只需要实现Job接口即可.

package com.dong.controller;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class jobtask implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        //所要执行的操作
    }
}

JobDetail对象:

    public static void main(String[] args) {
        JobDetail jobtask = newJob(jobTask.class)
                .withIdentity("jobone","jobA")
                .build();
    }

JobDetail对象,在上面的实例中,引入了JobBuilder类的静态方法newJob来创建job实例,withIdentity用来表示job的名字和所属组,build()方法则返回一个JobDetail实例.

JobDetail的源码解释为:

/**
 *Conveys the detail properties of a given <code>Job</code> instance. JobDetails are
 * to be created/defined with {@link JobBuilder}.
 * 
 * <p>
 * Quartz does not store an actual instance of a <code>Job</code> class, but
 * instead allows you to define an instance of one, through the use of a <code>JobDetail</code>.
 * </p>
**/

即Quartz不能存储Job实例,当Quartz需要Job的信息时,可定义JobDetail来存储Job属性,JobDetail通过JobBuilder创建.

 public static JobBuilder newJob(Class <? extends Job> jobClass) {
        JobBuilder b = new JobBuilder();
        b.ofType(jobClass);
        return b;
    }

Job的调度是通过scheduler实例,scheduler传入JobDetail对象和Trigger对象,JobDetail对象则在构造的过程中传入Job对象的class对象,可以看出这里使用反射的机制进行创建Job对象,当每次调用execute方法,则创建一个Job对象,然后丢弃该对象的引用,因此,Job对象必须有一个空参的构造器,其次,Job对象的属性值不会保存,如果想在Job对象执行中使用配置和属性,则可以使用JobDataMap.

public class jobTask implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        String name =context.getJobDetail().getJobDataMap().getString("name");
        System.out.println("name");
    }

    public static void main(String[] args) {
        JobDetail jobtask = newJob(jobTask.class)
                .withIdentity("jobone","jobA")
                .usingJobData("name","land")
                .build();
    }
}

JobDataMap可以包含数据对象,可在Job执行过程中,使用该对象的数据.

Trigger:触发器

Trigger公共属性:TriggerKey属性,表明Trigger身份,jobKey:Trigger被触发时被执行的Job身份,startTime属性:设置第一次触发时间,endTime属性:触发失效时间.错过触发misfire.

Trigger优先级,默认为5,可以是任意数值,注意只有同一时刻触发的trigger之间才会比较优先级.

calendar:不是Java的日历对象,这个对象用于从trigger的调度计划中排除时间段,创建Calendar需要实现Calendar接口,然后实例化改对象,并添加到scheduler对象中.对于一整天的排除,则可以使用HolidayCalendar对象,方法modifiedByCalendar()方法将在任务调度时,排除在该时间段的任务.

   public static void main(String[] args) {
        HolidayCalendar holidayCalendar = new HolidayCalendar();
        holidayCalendar.addExcludedDate("xxx");
        Trigger trigger = newTrigger()
                .withIdentity("triggerone")
                .forJob("job")
                .withSchedule(dailyAtHourAndMinute(12,00))
                .modifiedByCalendar("holidayCalendar")
                .build();
    }

Trigger两个子类有Siimple Trigger,Cron Trigger.

Simple Trigger:在特定的时间点支持,或者在特定的时间点执行,然后以特定的时间间隔执行.

CronTrigger 基于日历概念,使用CronTrigger需要指定时间表,Cron Expressions是用来定义日历的表达式,“0 0 12?* WED“ - 这意味着”每个星期三下午12:00“。

创建和Triigger对象相同,可以通过设置触发器的名字,开始时间,结束时间,执行次数,调度器,指定Job来实现任务的触发操作.

TriggerListeners和JobListeners:前者用来监听触发器,后者用来监听Job.***只需要实现TriggerListener或JobListeners接口即可,可以扩展JobListenerSupport类或TriggerListenerSupport类, listener与调度程序的ListenerManager一起注册,并配有描述listener希望接收事件的job/触发器的Matcher。

SchedulerListener***,包含各种监听Shceduler的事件,和TriggerListenners与JobListeners类型,需要注册到调度程序的ListennerManager。以JobListener为例:

package com.dong.controller;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;

public class JobLis implements JobListener {
    @Override
    public String getName() {
        return "jobpre";
    }
    @Override
    public void jobToBeExecuted(JobExecutionContext jobExecutionContext) {
        String name = jobExecutionContext.getJobDetail().getJobDataMap().getString("name");
        System.out.println("Job Start >...");

    }
    @Override
    public void jobExecutionVetoed(JobExecutionContext jobExecutionContext) {
    }
    @Override
    public void jobWasExecuted(JobExecutionContext jobExecutionContext, JobExecutionException e) {
        System.out.println("Job end >....");
    }
}

可通过jobExecutionContext来获取Job在运行时的一些数据.

Schedule:调度器

可通过StdSchedulerFactory,DirectSchedulerFactory来实现,也可通过schedulerFactory获取.

SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();
Scheduler scheduler = schedulerFactory.getScheduler();

Quartz在使用前,需要进行实例化,可以使用SchedulerFactory进行实例化,以工厂模式生成一个实例对象,scheduler实例化后,可启动,暂停,停止.除非scheduler启动,才可以进行相应的任务执行操作.

完整的任务调度案例:使用Maven方式创建工程

1.创建工程,pom.xml导入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.dong.quartz</groupId>
    <artifactId>quartz_helloworld</artifactId>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.2.RELEASE</version>
        <relativePath/>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.2.1</version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- 添加Scheduled坐标 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>

        <!-- Sprng tx 坐标 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
        </dependency>
    </dependencies>

</project>

    2.创建Job类

package com.dong.controller;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.stereotype.Component;

@Component
public class JobIns implements Job {
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("执行 Ququ  ...." );
    }
}

3.创建JobListeners

package com.dong.controller;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;

public class JobLis implements JobListener {
    @Override
    public String getName() {
        return "jobpre";
    }
    @Override
    public void jobToBeExecuted(JobExecutionContext jobExecutionContext) {
        String name = jobExecutionContext.getJobDetail().getJobDataMap().getString("name");
        System.out.println("Job Start >...");
    }
    @Override
    public void jobExecutionVetoed(JobExecutionContext jobExecutionContext) {
    }
    @Override
    public void jobWasExecuted(JobExecutionContext jobExecutionContext, JobExecutionException e) {
        System.out.println("Job end >....");
    }
}

4.创建Trigger Listenner

package com.dong.controller;

import org.quartz.JobExecutionContext;
import org.quartz.Trigger;
import org.quartz.TriggerListener;

public class TriggerLis implements TriggerListener {
    @Override
    public String getName() {
        return "triggerpre";
    }
    @Override
    public void triggerFired(Trigger trigger, JobExecutionContext jobExecutionContext) {
    }
    @Override
    public boolean vetoJobExecution(Trigger trigger, JobExecutionContext jobExecutionContext) {
        return false;
    }
    @Override
    public void triggerMisfired(Trigger trigger) {
    }
    @Override
    public void triggerComplete(Trigger trigger, JobExecutionContext jobExecutionContext, Trigger.CompletedExecutionInstruction completedExecutionInstruction) {
        System.out.println("trigger complete > .....");
    }
}

5.创建配合类,Simplejob,Trigger,Scheduler

package com.dong.config;

import com.dong.controller.JobLis;
import com.dong.controller.TriggerLis;
import com.dong.controller.JobIns;
import org.quartz.Scheduler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;

@Configuration
public class QuartzConfig {
        @Bean
        public JobDetailFactoryBean jobDetailFactoryBean(){
            JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean();
            jobDetailFactory.setJobClass(JobIns.class);
            return jobDetailFactory;
        }
        @Bean
        public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactory){
            SimpleTriggerFactoryBean simpleTriggerFactory = new SimpleTriggerFactoryBean();
            simpleTriggerFactory.setJobDetail(jobDetailFactory.getObject());
            simpleTriggerFactory.setRepeatInterval(2000);
            simpleTriggerFactory.setRepeatCount(20);
            return simpleTriggerFactory;
        }
        @Bean
        public SchedulerFactoryBean schedulerFactoryBean(SimpleTriggerFactoryBean simpleTriggerFactory){
            SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();
            schedulerFactory.setTriggers(simpleTriggerFactory.getObject());
            schedulerFactory.setGlobalJobListeners(new JobLis());
            schedulerFactory.setGlobalTriggerListeners(new TriggerLis());
            return schedulerFactory;
        }
}

    6.创建启动类

package com.dong.boot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;

@SpringBootApplication
@EnableScheduling
@ComponentScan("com.dong.*")
public class application {
    public static void main(String[] args) {
        SpringApplication.run(application.class,args);
    }
}

7.运行结果为:

Job Start >...
执行 Ququ  ....
Job end >....
trigger complete > .....
Job Start >...
执行 Ququ  ....
Job end >....
trigger complete > .....

 

 

         如有异议,敬请指出,与君共勉.