Quartz定时基础

1.Quartz简介
1.1 Quartz概要
1.1.1 定义
1.1.2 存储方式
1.1.3 表关系和解释:
1.1.4 核心类和关系
1.1.5 关系
1.2 Quartz体系结构
1.3开启多循环
2.Quartz详解
2.1 基础案例:每隔两秒打印helloWord:
2.2 Job和JobDetail
2.3 JobExecutionContext和JobDataMap
2.3.1获取JobDataMap:2种方式
1)从Map中直接获取--自定义参数
a.使用getJobDetail().getJobDataMap()调用任务,并在任务中使用自定义参数
b.使用getMergedJobDataMap获取传入的自定义的任务参数
2)job实现类中添加setter方法对应jobDataMap的键值
2.4 Trigger
Trigger通用属性
案例:设置开始结束时间
2.6 SimpleTrigger
2.7 CronTrigger
2.7.1案例:每s执行一次
2.7.2 Cron表达式
 
2.8 Scheduler:工厂模式
2.8.1 StdSchedulerFactory
2.8.2 Scheduler的主要函数
2.9 quartz.properties文件
2.9.1非持久化配置
2.9.2持久化配置
2.9.3 JDBC插入表顺序
3.Spring、Quartz整合
3.1使用Quartz配置作业
MethodInvokingJobDetailFactoryBean
JobDetailFactoryBean
判断cron格式是否正确
cron获取下次运行时间

TOC

1.Quartz简介

1.1 Quartz概要

1.1.1 定义

-  OpenSymphony提供的强大的开源任务调度框架
- 官网:http://www.quartz-scheduler.org/
- 纯Java实现,精细控制排程
  • 特点

    • 强大的调度功能
    • 灵活的应用方式
    • 分布式和集群能力
  • 主要用到的设计模式
    • Builder模式
    • Factory模式
    • 组件模式
    • 链式写法

1.1.2 存储方式

- RAMJobStore
- JDBCJobStore

类型

优点

缺点

RAMJobStore

不要外部数据库,配置容易,运行速度快 因为调度程序信息是存储在被分配给JVM的内存里面,所以,当应用程序停止运行时,所有调度信息将被丢失。另外因为存储到JVM内存里面,所以可以存储多少个Job和Trigger将会受到限制

JDBCJobStore

支持集群,因为所有的任务信息都会保存到数据库中,可以控制事物,还有就是如果应用服务器关闭或者重启,任务信息都不会丢失,并且可以恢复因服务器关闭或者重启而导致执行失败的任务 运行速度的快慢取决与连接数据库的快慢

1.1.3 表关系和解释:

- 表关系

  • 解释

表名称 说明

qrtz_blob_triggers Trigger作为Blob类型存储(用于Quartz用户用JDBC创建他们自己定制的Trigger类型,JobStore 并不知道如何存储实例的时候)

qrtz_calendars 以Blob类型存储Quartz的Calendar日历信息, quartz可配置一个日历来指定一个时间范围

qrtz_cron_triggers 存储Cron Trigger,包括Cron表达式和时区信息。

qrtz_fired_triggers 存储与已触发的Trigger相关的状态信息,以及相联Job的执行信息

qrtz_job_details 存储每一个已配置的Job的详细信息

qrtz_locks 存储程序的非观锁的信息(假如使用了悲观锁)

qrtz_paused_trigger_graps 存储已暂停的Trigger组的信息

qrtz_scheduler_state 存储少量的有关 Scheduler的状态信息,和别的 Scheduler 实例(假如是用于一个集群中)

qrtz_simple_triggers 存储简单的 Trigger,包括重复次数,间隔,以及已触的次数

qrtz_triggers 存储已配置的 Trigger的信息

qrzt_simprop_triggers

1.1.4 核心类和关系

  • 核心类

    • QuartzSchedulerThread:负责执行向QuartzScheduler注册的触发Trigger的工作的线程。
    • ThreadPool:Scheduler使用一个线程池作为任务运行的基础设施,任务通过共享线程池中的线程提供运行效率。
    • QuartzSchedulerResources:包含创建QuartzScheduler实例所需的所有资源(JobStore,ThreadPool等)。
    • SchedulerFactory :提供用于获取调度程序实例的客户端可用句柄的机制。
    • JobStore: 通过类实现的接口,这些类要为org.quartz.core.QuartzScheduler的使用提供一个org.quartz.Joborg.quartz.Trigger存储机制。作业和触发器的存储应该以其名称和组的组合为唯一性。
    • QuartzScheduler :这是Quartz的核心,它是org.quartz.Scheduler接口的间接实现,包含调度org.quartz.Jobs,注册org.quartz.JobListener实例等的方法。
    • Scheduler :这是Quartz Scheduler的主要接口,代表一个独立运行容器。调度程序维护JobDetails和触发器的注册表。 一旦注册,调度程序负责执行作业,当他们的相关联的触发器触发(当他们的预定时间到达时)。
    • Trigger :具有所有触发器通用属性的基本接口,描述了job执行的时间出发规则。(使用TriggerBuilder实例化实际触发器。 )
    • JobDetail :传递给定作业实例的详细信息属性。 JobDetails将使用JobBuilder创建/定义。
    • Job:要由表示要执行的“作业”的类实现的接口。只有一个方法 void execute(jobExecutionContext context)

         (jobExecutionContext 提供调度上下文各种信息,运行时数据保存在jobDataMap中)

         Job有个子接口StatefulJob ,代表有状态任务。

         有状态任务不可并发,前次任务没有执行完,后面任务处于阻塞等到。

1.1.5 关系

 

一个job可以被多个Trigger 绑定,但是一个Trigger只能绑定一个job!

 

1.2 Quartz体系结构

三个核心嘅念

  • 调度器:schedule
  • 任务:JobDetail
  • 触发器:trigger
    • SimpleTrigger
    • CronTrigger

重要组成

  • Job
  • JobDetail
  • JobBuilder
  • JobStore
  • Trigger
  • TriggerBuilder
  • ThreadPool
  • Scheduler
    • Calendar

      • 一个Trigger可以和多个Calendar关联,以排除或包含某些时间点。
    • 监听器
      • JobListener,TriggerListener,SchedulerListenero

1.3开启多循环

  • 注意:jobDetail和trigger是一对一的,要想让一个任务启动多次,要设计不同的jobDetail和trigger

    比如:

每次传入不同的string即可开启开启多个循环
jobDetail:   .withIdentity("myJob"+string,"group")

trigger:   .withIdentity("myTrigger"+string, "group")

结果:

调用两次,分别传入111和nihao:
  开启了两个循环
当123前线程+DefaultQuartzScheduler_Worker-7自定义值111
当123前线程+DefaultQuartzScheduler_Worker-8自定义值nihao
当123前线程+DefaultQuartzScheduler_Worker-9自定义值111
当123前线程+DefaultQuartzScheduler_Worker-10自定义值nihao

2.Quartz详解

2.1 基础案例:每隔两秒打印helloWord:

  • pom
        <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>
        <dependency><!-- 该依赖必加,里面有sping对schedule的支持 -->
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
  • 运行的方法
public class HelloJob implements Job {//继承Job

    public void execute(JobExecutionContext context) throws JobExecutionException {//编写具体的业务逻辑
        try {
            Thread.sleep(5000L);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // 打印当前的执行时间,格式为2017-01-01 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("Current Exec Time Is : " + sf.format(date));
        System.out.println("Hello World");
    }
}
  • schedule,调用任务
public class HelloScheduler {
    public static void main(String[] args) throws SchedulerException, InterruptedException {
        // 打印当前的时间,格式为2017-01-01 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("Current Time Is : " + sf.format(date));
        // 1.创建一个JobDetail实例,将该实例与HelloJob Class绑定
        JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)//绑定方法
                .withIdentity("myJob", "group1").build();//创建唯一标示:myJob,这里的组可以不写
        // 1.创建一个trigger实例,定义job立即执行,每2s执行一次
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("myTrigger", "group1") //设置唯一标示和组
                //注意:虽然trigger和jobDetail组名一致,但是不是同一个类,所以不是同一个组
                //现在开始执行,执行频度
                .startNow().withSchedule(SimpleScheduleBuilder.simpleSchdule().withIntervalInSeconds(2).repeatForever().build();
        // 创建Scheduler实例
        SchedulerFactory sfact = new StdSchedulerFactory();
        Scheduler scheduler = sfact.getScheduler();
        scheduler.start();//开始执行
        System.out.println("scheduled time is :"
                + sf.format(date));//将jobDetail, trigger绑定在一起
scheduler.scheduleJob(jobDetail, trigger);
    }
}

2.2 Job和JobDetail

  • job定义

    • 实现业务逻辑的任务接口;
    • job接口非常容易实现,只有一个execute方法,类似TimerTask的run方法,在里面编写业务逻辑;
  • job实例在Quartz中的生命周期:
    • 每次调度器执行job时,它在调用e×ecute方法前会创建一个新的job实例。
    • 当调用完成后,关联的job对象实例会被释放,释放的实例会被垃圾回收机制回收。

  • JobDetail

    • JobDetail为Job实例提供了许多设置属性,以及JobDataMap成员变量属性,它用来存储特定job实例的状态信息,调度器需要借助JobDetail对象来添加job实例。
    • 是用来绑定job并携带job需要用到的信息。
  • JobDetail重要属性:
    • name:(任务名称必须)
    • group(组,必须(有默认值DEFAULT))
    • jobClass(任务实现类,必须)
    • jobDataMap(传参)
  • 获取JobDetail信息
    • jobDetail.getKey().getName());//任务名称
    • jobDetail.getKey().getGroup());//组,默认是DEFAULT
    • jobDetail.getJobClass().getName()//任务class名,全类名

2.3 JobExecutionContext和JobDataMap

  • JobExecutionContext是什么

    • 当Scheduler调用一个job,就会将JobExecutionContext传递给b的execute()方法,
    • Job能通过JobExecutionContext对象访问到Quartz运行时候的环境以及job本身的明细数据。
  • JobDataMap是什么
    • 在进行任务调度时jobDataMap存储在JobExecutionContext中,非常方便获取。
    • JobDataMap可以用来装载任何可序列化的数据对象,当job实例对象被执行时这些参数对象会传递给它。
    • JobDataMap实现了JDK的Map接口,并且添加了一些非常方便的方法用来存取基本数据类型

2.3.1获取JobDataMap:2种方式

1)从Map中直接获取--自定义参数

  • 使用JobDetail和trigger给任务添加自定义的参数
@RestController
public class HelloScheduler {
    @RequestMapping("/t1")
    public  void t1() throws SchedulerException, InterruptedException {
        // 1.创建一个JobDetail实例,将该实例与HelloJob Class绑定
        JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)//绑定方法
                .withIdentity("myJob")
                .usingJobData("message","hello myjob1")//传入自定义参数
                .usingJobData("FloatJobValue",3.14f).build();//创建唯一标示:myJob
        // 1.创建一个trigger实例,定义job立即执行,每2s执行一次
        Trigger trigger = TriggerBuilder
                .newTrigger()
                .withIdentity("myTrigger", "group1") //设置唯一标示和组
                .usingJobData("message","hello myTrigger1")
                .usingJobData("DoubleTriggerValue",2.0D)
                .startNow()
                .withSchedule(
                        SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).repeatForever())
                .build();
        // 创建Scheduler实例
        SchedulerFactory sfact = new StdSchedulerFactory();
        Scheduler scheduler = sfact.getScheduler();
   //启动任务
        scheduler.start();
        // 打印当前的时间,格式为2017-01-01 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("Current Time Is : " + sf.format(date));
        scheduler.scheduleJob(jobDetail, trigger);
    }

}
a.使用getJobDetail().getJobDataMap()调用任务,并在任务中使用自定义参数
public class HelloJob implements Job {//继承Job
    public void execute(JobExecutionContext context) throws JobExecutionException {//编写具体的业务逻辑
        // 打印当前的执行时间,格式为2017-01-01 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("Current Exec Time Is : " + sf.format(date));
        //System.out.println("Hello World");
        //打印JobDetail信息
        JobKey  key=context.getJobDetail().getKey();
        System.out.println("My job name and group are:"+key.getName()+":"+key.getGroup());
        //打印trigger信息
        TriggerKey triggerKey=context.getTrigger().getKey();
        System.out.println("My trigger name and group are:"+triggerKey.getName()+":"+triggerKey.getGroup());
        //打印自定义传入的数据
        JobDataMap dataMap=context.getJobDetail().getJobDataMap();
        JobDataMap tDataMap=context.getTrigger().getJobDataMap();
        String jobMsg=dataMap.getString("message");
        Float jobFloatValue=dataMap.getFloat("FloatJobValue");
        String triggerMsg=tDataMap.getString("message");

        Double triggerDoubleValue=tDataMap.getDouble("DoubleTriggerValue");
        System.out.println("JobMsg is"+jobMsg);
        System.out.println("jobFloatValue is"+jobFloatValue);
        System.out.println("triggerMsg is"+triggerMsg);
        System.out.println("triggerDoubleValue is"+triggerDoubleValue);
    }
}
  • 结果
Current Exec Time Is : 2018-07-03 19:09:46 //启动任务
My job name and group are:myJob:DEFAULT  //DEFAULT 是默认的组名
My trigger name and group are:myTrigger:group1
JobMsg ishello myjob1
jobFloatValue is3.14
triggerMsg ishello myTrigger1
triggerDoubleValue is2.0
Current Exec Time Is : 2018-07-03 19:09:48
My job name and group are:myJob:DEFAULT
My trigger name and group are:myTrigger:group1
JobMsg ishello myjob1
jobFloatValue is3.14

b.使用getMergedJobDataMap获取传入的自定义的任务参数
public class HelloJob implements Job {//继承Job
    public void execute(JobExecutionContext context) throws JobExecutionException {//编写具体的业务逻辑
        // 打印当前的执行时间,格式为2017-01-01 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("Current Exec Time Is : " + sf.format(date));
        //System.out.println("Hello World");
        //打印JobDetail信息
        JobKey  key=context.getJobDetail().getKey();
        System.out.println("My job name and group are:"+key.getName()+":"+key.getGroup());
        //打印trigger信息
        TriggerKey triggerKey=context.getTrigger().getKey();
        System.out.println("My trigger name and group are:"+triggerKey.getName()+":"+triggerKey.getGroup());
        //打印自定义传入的数据
        //getMergedJobDataMap是JobDataMap,Trigger合并后 的
        JobDataMap dataMap=context.getMergedJobDataMap();//getTrigger().getJobDataMap();
        //JobDataMap,Trigger中message是想相同的,会显示Trigger中的
        String msg=dataMap.getString("message");
        Float jobFloatValue=dataMap.getFloat("FloatJobValue");
        Double triggerDoubleValue=dataMap.getDouble("DoubleTriggerValue");
        System.out.println("JobMsg is"+msg);
        System.out.println("jobFloatValue is"+jobFloatValue);
        System.out.println("triggerDoubleValue is"+triggerDoubleValue);
    }
}
  • 结果
Current Exec Time Is : 2018-07-03 19:23:26
My job name and group are:myJob:DEFAULT
My trigger name and group are:myTrigger:group1
JobMsg ishello myTrigger1  //显示的是Trigger的
jobFloatValue is3.14  //打印的是对应的
triggerDoubleValue is2.0

2)job实现类中添加setter方法对应jobDataMap的键值

  • Quartz框架默认的jobFactory实现类在初始化job实例对象时会自动地调用这些setter方法
  • 实质:创建与key对应的参数,生成getset方法即可获取。
  • 使用第二种方法从任务中获取参数
//方法2,直接传入参数
public class HelloJob implements Job {//继承Job
    private String  message;//要与传入的数据的key对应
    private Float  FloatJobValue;
    private Double  DoubleTriggerValue;
    //生成getset方法
    public void execute(JobExecutionContext context) throws JobExecutionException {//编写具体的业务逻辑
        // 打印当前的执行时间,格式为2017-01-01 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("Current Exec Time Is : " + sf.format(date));
        //System.out.println("Hello World");
        //打印JobDetail信息
        JobKey  key=context.getJobDetail().getKey();
        System.out.println("My job name and group are:"+key.getName()+":"+key.getGroup());
        //打印trigger信息
        TriggerKey triggerKey=context.getTrigger().getKey();
        System.out.println("My trigger name and group are:"+triggerKey.getName()+":"+triggerKey.getGroup());
        //打印自定义传入的数据
        //JobDataMap,Trigger中message是想相同的,会显示Trigger中的
        System.out.println("JobMsg is"+message);
        System.out.println("jobFloatValue is"+FloatJobValue);
        System.out.println("triggerDoubleValue is"+DoubleTriggerValue);
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public Float getFloatJobValue() {
        return FloatJobValue;
    }
    public void setFloatJobValue(Float floatJobValue) {
        FloatJobValue = floatJobValue;
    }
    public Double getDoubleTriggerValue() {
        return DoubleTriggerValue;
    }
    public void setDoubleTriggerValue(Double doubleTriggerValue) {
        DoubleTriggerValue = doubleTriggerValue;
    }
}
  • 结果
Current Exec Time Is : 2018-07-03 19:33:25
My job name and group are:myJob:DEFAULT
My trigger name and group are:myTrigger:group1
JobMsg ishello myTrigger1
jobFloatValue is3.14
triggerDoubleValue is2.0

2.4 Trigger

  • Trigger概述:

      Quartz中的触发器用来告诉调度程序作业什么时候触发。即Trigger对象是用来触发执行job的。

    Quartz框架中的Trigger:

Trigger通用属性

  • JobKey:表示job实例的标识,触发器被触发时,该指定Job实例会执行。
  • StartTime:表示触发器的时间表首次被触发的时间。它的值的类型是Java.util.Date.
  • EndTime:指定触发器的不再被触发的时间。它的值的类型是Java.util.Date.

案例:设置开始结束时间

  • 任务
public class HelloJob implements Job {//继承Job
    private String  message;//要与传入的数据的key对应
    private Float  FloatJobValue;
    private Double  DoubleTriggerValue;
    //生成getset方法
    public void execute(JobExecutionContext context) throws JobExecutionException {//编写具体的业务逻辑
        // 打印当前的执行时间,格式为2017-01-01 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("任务HelloJob开始时间 : " + sf.format(date));
        //获取定义的开始时间,和结束时间
        Trigger cunrrentTrigger= context.getTrigger();
        System.out.println("开始时间:"+sf.format(cunrrentTrigger.getStartTime()));
        System.out.println("结束时间:"+sf.format(cunrrentTrigger.getEndTime()));
        JobKey  key=cunrrentTrigger.getJobKey();
        System.out.println("JobKey信息:name:"+key.getName()+" group:"+key.getGroup());
    }
  • 调用任务
@RestController
public class HelloScheduler {
    @RequestMapping("/t1")
    public  void t1() throws SchedulerException, InterruptedException {
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("controller方法 t1开始时间: " + sf.format(date));
        // 1.创建一个JobDetail实例,将该实例与HelloJob Class绑定
        JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)//绑定方法
                .withIdentity("myJob").build();//创建唯一标示:myJob
        // 1.创建一个trigger实例,
        //获取距离当前时间date,3秒后的时间
        date.setTime(date.getTime()+3000);//3秒后的时间
        Date enDate=new Date();
        enDate.setTime(enDate.getTime()+6000);//6秒后的时间
        Trigger trigger = TriggerBuilder
                .newTrigger()
                .withIdentity("myTrigger", "group1") //设置唯一标示和组
                .startAt(date)//设置开始时间:3秒后的时间
                .endAt(enDate)//设置结束时间,6s后停止
                //每2s执行一次的话,会在第3s执行第一次,第5s执行第二次
                .withSchedule(
                        //设置任务每2s执行一次
                        SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).repeatForever())
                .build();
        // 创建Scheduler实例
        SchedulerFactory sfact = new StdSchedulerFactory();
        Scheduler scheduler = sfact.getScheduler();
        scheduler.scheduleJob(jobDetail, trigger);
        // 打印当前的时间,格式为2017-01-01 00:00:00
        scheduler.start();

    }
}
  • 结果
-----任务只执行了两次,58-013s,在58和00执行的。
controller方法 t1开始时间: 2018-07-04 09:21:55  //开始时间
2018-07-04 09:21:55.852  INFO 9320 --- [nio-8087-exec-3] org.quartz.core.QuartzScheduler          : Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.
任务HelloJob开始时间 : 2018-07-04 09:21:58 //3s后第一次执行
开始时间:2018-07-04 09:21:58
结束时间:2018-07-04 09:22:01  //6s后结束
JobKey信息:name:myJob group:DEFAULT
任务HelloJob开始时间 : 2018-07-04 09:22:00
开始时间:2018-07-04 09:21:58
结束时间:2018-07-04 09:22:01
JobKey信息:name:myJob group:DEFAULT

2.6 SimpleTrigger

  • SimpleTrigger的作用

    在一个指定时间段执行一次作业任务或是在指定的时间间隔多次执行作业任务

  • 在一个指定时间段执行一次作业任务

    4秒后只执行一次

  • 注意
    • 重复次数可以为0,正整数或是SimpleTrigger.REPEAT_INDEFINITELY常量值.
    • 重复执行间隔必须为0或长整数.
    • 一旦被指定了endTime参数,那么它会覆盖重复次数参数的效果(若是还未到运行时间,任务就运行完了,会停止).
  • withRepeatCount是重复的次数,真正运行的次数是withRepeatCount+1(withRepeatCount==0的时候,会运行一次)
@RestController
public class HelloScheduler {
    @RequestMapping("/t1")
    public  void t1() throws SchedulerException, InterruptedException {
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("controller方法 t1开始时间: " + sf.format(date));
        // 1.创建一个JobDetail实例,将该实例与HelloJob Class绑定
        JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)//绑定方法
                .withIdentity("myJob").build();//创建唯一标示:myJob
        // 1.创建一个trigger实例,
        //获取距离当前时间4秒后的时间,只执行一次
        date.setTime(date.getTime()+4000l);
        SimpleTrigger trigger = (SimpleTrigger)TriggerBuilder
                .newTrigger()
                .withIdentity("myTrigger", "group1") //设置唯一标示id和组
                .startAt(date)
                .build();
        // 创建Scheduler实例
        SchedulerFactory sfact = new StdSchedulerFactory();
        Scheduler scheduler = sfact.getScheduler();
        scheduler.scheduleJob(jobDetail, trigger);
        // 打印当前的时间,格式为2017-01-01 00:00:00
        scheduler.start();
    }
}

  • 指定的时间间隔多次执行**作业任务

    4s后,开始执行,之后每隔2s中执行一次

        date.setTime(date.getTime()+4000l);
        SimpleTrigger trigger = (SimpleTrigger)TriggerBuilder
                .newTrigger()
                .withIdentity("myTrigger", "group1") //设置唯一标示id和组
                .startAt(date)
                .withSchedule(
                        SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2)//每2s执行一次
                        .withRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY))//执行无限次
                .build();
  • 4s后开始执行,每2s执行一次,执行无限次,6s后停止
        //6s后停止执行
        Date enDate=new Date();
        enDate.setTime(enDate.getTime()+6000l);
        date.setTime(date.getTime()+4000l);
        SimpleTrigger trigger = (SimpleTrigger)TriggerBuilder
                .newTrigger()
                .withIdentity("myTrigger", "group1") //设置唯一标示id和组
                .startAt(date)
                .endAt(enDate)//6s后停止执行
                .withSchedule(
                        SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2)//每2s执行一次
                        .withRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY))//执行无限次
                .build();

2.7 CronTrigger

  • CronTrigger作用

    • 基于日历作业调度器,而不是像SimpleTrigger那样精确指定间隔时间,比SimpleTrigge更常用。
  • Cron表达式
    • 用于配置CronTrigger实例。
    • 是由7个子表达式组成的字符串,描述了时间表的详细信息。
    • 格式:【秒】【分】【小时】【日】】【月】【周】【年】

2.7.1案例:每s执行一次

CronTrigger trigger = (CronTrigger)TriggerBuilder
    .newTrigger()
    .withIdentity("myTrigger", "group1") //设置唯一标示id和组
    .withSchedule(
        CronScheduleBuilder.cronSchedule("* * * * * ? *"))
    .build();

2.7.2 Cron表达式

  • 特殊字符意义对应表

  • Cron表达式举例

    • 每天的14点整至14点59分55秒,以及18点整至18点59分55秒。每5秒钟触发1次:0/5 * 14,18 * * ?

      由于每5s执行一次,所以到55的时候执行最后一次,下一次是下一分的开始或结束此次运行

  • 通配符说明

  • Cron表达式小提示
    • ‘L‘和‘W‘可以组合使用。
    • 周字段英文字母不区分大小写即MON与mon相同
    • 利用工具,在线生成

        

 

2.8 Scheduler:工厂模式

  • 所有的Scheduler实例应该由SchedulerFactory来创建

  • Scheduler的创建方式
SchedulerFactory sfact=new StdSchedulerFactory();
Scheduler scheduler=sfact.getScheduler();
DirectSchedulerFactory factory=DirectSchedulerFactory.getInstance();
Scheduler scheduler=factory.getScheduler();

2.8.1 StdSchedulerFactory

  1. 使用一组参数(Java.util.Properties)来创建和初始化Quartz调度器
  2. 配置参数一般存储在quartz.properties
  3. 调用getScheduler方法就能创建和初始化调度器对象

2.8.2 Scheduler的主要函数


1. Date scheduleJob(JobDetail jobDetail,Trigger trigger)  //是在项目中,启动任务,设置任务和时间的
2. void start()  //启动Scheduler
3. void standby()  //让Scheduler暂时挂起,暂停
4. void shutdown() //将任务关闭,不能用start重启,会报错
    shutdown(true) //表示等待所有正在执行的job执行完毕之后,再关闭scheduler,此时是等一次任务运行完成,才会运行shutdown代码及之后的代码

    shutdown(false)  //即shutdowno()表示直接关闭scheduler,直接运行shutdown代码,任务在另一个线程上继续,直到运行完这一次任务
5. scheduler.isShutdown();//判断scheduler是否关闭
  • 案例
// 创建Scheduler实例
SchedulerFactory sfact = new StdSchedulerFactory();
Scheduler scheduler = sfact.getScheduler();
System.out.println("返回值:"+sf.format(scheduler.scheduleJob(jobDetail, trigger)));
// 打印当前的时间,格式为2017-01-01 00:00:00
 scheduler.start();

//让Scheduler执行2s后自动挂起
Thread.sleep(2000L);//睡眠2s,此时任务的线程还在运行
scheduler.standby();//2s后,任务挂起

//让Scheduler挂起,3s后,启动
Thread.sleep(3000l);
scheduler.start();

结果:

返回值:2018-07-04 19:16:18  //最近一次任务将要运行的时间
任务HelloJob开始时间 : 2018-07-04 19:16:18

Hello World
任务HelloJob开始时间 : 2018-07-04 19:16:19
Hello World
任务HelloJob开始时间 : 2018-07-04 19:16:20 //2s后
Hello World
//任务挂起
//3s后,任务开始再次执行
任务HelloJob开始时间 : 2018-07-04 19:16:23

Hello World
任务HelloJob开始时间 : 2018-07-04 19:16:23
Hello World
任务HelloJob开始时间 : 2018-07-04 19:16:23
Hello World
任务HelloJob开始时间 : 2018-07-04 19:16:24
Hello World
任务HelloJob开始时间 : 2018-07-04 19:16:25
Hello World
任务HelloJob开始时间 : 2018-07-04 19:16:26
Hello World
任务HelloJob开始时间 : 2018-07-04 19:16:27
Hello World

//之后便是一直运行了

2.9 quartz.properties文件

  • 文档的位置和加载顺序:

    需要自己建立,默认在jar包中有

    放到resource中即可

  • 组成部分
    • 调度器属性:

      • org.quartz.scheduler.instanceName属性用来区分特定的调度器实例,可以按照功能用途来给调度器起名。
      • org.quartz.scheduler.instanceId属性和前者一样,也允许任何字符串,但这个值必须是在所有调度器实例中是唯一的,尤其是在一个集群当中,作为集群的唯一key.假如你想Quartz帮你生成这个值的话,可以设置为AUTO。
    • 线程池属性:
    • threadCount:设置工作线程数:(无默认值,必须设置,1-100最好)
    • threadPriority:设置工作优先级:(1-10,默认5,主要用在集群)
    • org.quartz.threadPool.class
    • 作业存储设置:
    • 描述了在调度器实例的生命周期中,Job和Trigger信息是如何被存储的。
    • 插件配置:
    • 满足特定需求用到的Quartz插件的配置。

2.9.1非持久化配置

# ===========================================================================
# Configure Main Scheduler Properties 调度器属性
# ===========================================================================
#调度标识名 集群中每一个实例都必须使用相同的名称 (区分特定的调度器实例)
org.quartz.scheduler.instanceName: DefaultQuartzScheduler
#ID设置为自动获取 每一个必须不同 (所有调度器实例中是唯一的)
org.quartz.scheduler.instanceid:AUTO #自增
org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false
# ===========================================================================
# Configure ThreadPool 线程池属性
# ===========================================================================
#线程池的实现类(一般使用SimpleThreadPool即可满足几乎所有用户的需求)
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
#指定线程数,至少为1(无默认值)(一般设置为1-100直接的整数合适)
org.quartz.threadPool.threadCount: 10
#设置线程的优先级(最大为java.lang.Thread.MAX_PRIORITY 10,最小为Thread.MIN_PRIORITY 1,默认为5)
org.quartz.threadPool.threadPriority: 5
#设置SimpleThreadPool的一些属性
#设置是否为守护线程
#org.quartz.threadpool.makethreadsdaemons = false
#org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true
#org.quartz.threadpool.threadsinheritgroupofinitializingthread=false
#线程前缀默认值是:[Scheduler Name]_Worker
#org.quartz.threadpool.threadnameprefix=swhJobThead;
# 配置全局监听(TriggerListener,JobListener) 则应用程序可以接收和执行 预定的事件通知
# ===========================================================================
# Configuring a Global TriggerListener 配置全局的Trigger监听器
# MyTriggerListenerClass 类必须有一个无参数的构造函数,和 属性的set方法,目前2.2.x只支持原始数据类型的值(包括字符串)
# ===========================================================================
#org.quartz.triggerListener.NAME.class = com.swh.MyTriggerListenerClass
#org.quartz.triggerListener.NAME.propName = propValue
#org.quartz.triggerListener.NAME.prop2Name = prop2Value
# ===========================================================================
# Configuring a Global JobListener 配置全局的Job监听器
# MyJobListenerClass 类必须有一个无参数的构造函数,和 属性的set方法,目前2.2.x只支持原始数据类型的值(包括字符串)
# ===========================================================================
#org.quartz.jobListener.NAME.class = com.swh.MyJobListenerClass
#org.quartz.jobListener.NAME.propName = propValue
#org.quartz.jobListener.NAME.prop2Name = prop2Value
# ===========================================================================
# Configure JobStore 存储调度信息(工作,触发器和日历等)
# ===========================================================================
# 信息保存时间 默认值60秒
org.quartz.jobStore.misfireThreshold: 60000
#保存job和Trigger的状态信息到内存中的类,没有持久化
org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
# ===========================================================================
# Configure SchedulerPlugins 插件属性 配置
# ===========================================================================
# 自定义插件
#org.quartz.plugin.NAME.class = com.swh.MyPluginClass
#org.quartz.plugin.NAME.propName = propValue
#org.quartz.plugin.NAME.prop2Name = prop2Value
#配置trigger执行历史日志(可以看到类的文档和参数列表)
org.quartz.plugin.triggHistory.class = org.quartz.plugins.history.LoggingTriggerHistoryPlugin
org.quartz.plugin.triggHistory.triggerFiredMessage = Trigger {1}.{0} fired job {6}.{5} at: {4, date, HH:mm:ss MM/dd/yyyy}
org.quartz.plugin.triggHistory.triggerCompleteMessage = Trigger {1}.{0} completed firing job {6}.{5} at {4, date, HH:mm:ss MM/dd/yyyy} with resulting trigger instruction code: {9}
#配置job调度插件 quartz_jobs(jobs and triggers内容)的XML文档
#加载 Job 和 Trigger 信息的类 (1.8之前用:org.quartz.plugins.xml.JobInitializationPlugin)
org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
#指定存放调度器(Job 和 Trigger)信息的xml文件,默认是classpath下quartz_jobs.xml
org.quartz.plugin.jobInitializer.fileNames = my_quartz_job2.xml
#org.quartz.plugin.jobInitializer.overWriteExistingJobs = false
org.quartz.plugin.jobInitializer.failOnFileNotFound = true
#自动扫描任务单并发现改动的时间间隔,单位为秒
org.quartz.plugin.jobInitializer.scanInterval = 10
#覆盖任务调度器中同名的jobDetail,避免只修改了CronExpression所造成的不能重新生效情况
org.quartz.plugin.jobInitializer.wrapInUserTransaction = false
# ===========================================================================
# Sample configuration of ShutdownHookPlugin ShutdownHookPlugin插件的配置样例
# ===========================================================================
#org.quartz.plugin.shutdownhook.class = \org.quartz.plugins.management.ShutdownHookPlugin
#org.quartz.plugin.shutdownhook.cleanShutdown = true
#
# Configure RMI Settings 远程服务调用配置
#
#如果你想quartz-scheduler出口本身通过RMI作为服务器,然后设置“出口”标志true(默认值为false)。
#org.quartz.scheduler.rmi.export = false
#主机上rmi注册表(默认值localhost)
#org.quartz.scheduler.rmi.registryhost = localhost
#注册监听端口号(默认值1099)
#org.quartz.scheduler.rmi.registryport = 1099
#创建rmi注册,false/never:如果你已经有一个在运行或不想进行创建注册
# true/as_needed:第一次尝试使用现有的注册,然后再回来进行创建
# always:先进行创建一个注册,然后再使用回来使用注册
#org.quartz.scheduler.rmi.createregistry = never
#Quartz Scheduler服务端端口,默认是随机分配RMI注册表
#org.quartz.scheduler.rmi.serverport = 1098
#true:链接远程服务调度(客户端),这个也要指定registryhost和registryport,默认为false
# 如果export和proxy同时指定为true,则export的设置将被忽略
#org.quartz.scheduler.rmi.proxy = false

2.9.2持久化配置

//调度标识名 集群中每一个实例都必须使用相同的名称 (区分特定的调度器实例)
org.quartz.scheduler.instanceName:DefaultQuartzScheduler
//ID设置为自动获取 每一个必须不同 (所有调度器实例中是唯一的)
org.quartz.scheduler.instanceId :AUTO
//数据保存方式为持久化
org.quartz.jobStore.class :org.quartz.impl.jdbcjobstore.JobStoreTX
//表的前缀
org.quartz.jobStore.tablePrefix : QRTZ_
//设置为TRUE不会出现序列化非字符串类到 BLOB 时产生的类版本问题
//org.quartz.jobStore.useProperties : true
//加入集群 true 为集群 false不是集群
org.quartz.jobStore.isClustered : false
//调度实例失效的检查时间间隔
org.quartz.jobStore.clusterCheckinInterval:20000
//容许的最大作业延长时间
org.quartz.jobStore.misfireThreshold :60000
//ThreadPool 实现的类名
org.quartz.threadPool.class:org.quartz.simpl.SimpleThreadPool
//线程数量
org.quartz.threadPool.threadCount : 10
//线程优先级
org.quartz.threadPool.threadPriority : 5(threadPriority 属性的最大值是常量 java.lang.Thread.MAX_PRIORITY,等于10。最小值为常量 java.lang.Thread.MIN_PRIORITY,为1)
//自创建父线程
//org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true
//数据库别名
org.quartz.jobStore.dataSource : qzDS
//设置数据源
org.quartz.dataSource.qzDS.driver:com.mysql.jdbc.Driver
org.quartz.dataSource.qzDS.URL:jdbc:mysql://localhost:3306/quartz
org.quartz.dataSource.qzDS.user:root
org.quartz.dataSource.qzDS.password:123456
org.quartz.dataSource.qzDS.maxConnection:10

2.9.3 JDBC插入表顺序

主要的JDBC操作类,执行sql顺序。

Simple_trigger :插入顺序

qrtz_job_details —> qrtz_triggers —> qrtz_simple_triggers

qrtz_fired_triggers

Cron_Trigger:插入顺序

qrtz_job_details —> qrtz_triggers —> qrtz_cron_triggers

qrtz_fired_triggers

3.Spring、Quartz整合

  • pom
        <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>
        <dependency><!-- 该依赖必加,里面有sping对schedule的支持 -->
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
<!--spring的事务,不确定。。。。-->
        <dependency><!-- 该依赖必加,里面有sping对schedule的支持 -->
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
        </dependency>

3.1使用Quartz配置作业

  • 两种方式

    • MethodInvokingJobDetailFactoryBean
    • JobDetailFactoryBean

MethodInvokingJobDetailFactoryBean

调用myBean的printMessage方法

MyBean类:

@Component("myBean")
public class MyBean {
 public void printMessage() {
  // 打印当前的执行时间,格式为2017-01-01 00:00:00
  Date date = new Date();
  SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  System.out.println("MyBean Executes!" + sf.format(date));
 }
}

JobDetailFactoryBean

需要给作业传递数据,想更加灵活的话就使用这种方式

public class FirstScheduledJob extends QuartzJobBean{
     private AnotherBean anotherBean;

     public void setAnotherBean(AnotherBean anotherBean){
      this.anotherBean = anotherBean;
     }

 @Override
 protected void executeInternal(JobExecutionContext arg0)
   throws JobExecutionException {
  Date date = new Date();
  SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  System.out.println("FirstScheduledJob Executes!" + sf.format(date));
  this.anotherBean.printAnotherMessage();
 }
}
@Component("anotherBean")
public class AnotherBean {
 public void printAnotherMessage() {
  System.out.println("AnotherMessage");
 }
}

配置:

<?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:context="http://www.springframework.org/schema/context"
 xmlns:mvc="http://www.springframework.org/schema/mvc" 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
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd"
 default-lazy-init="true">

 <!-- 通过mvc:resources设置静态资源,这样servlet就会处理这些静态资源,而不通过控制器 -->
 <!-- 设置不过滤内容,比如:css,jquery,img 等资源文件 -->
 <mvc:resources location="/*.html" mapping="/**.html" />
 <mvc:resources location="/css/*" mapping="/css/**" />
 <mvc:resources location="/js/*" mapping="/js/**" />
 <mvc:resources location="/images/*" mapping="/images/**" />
 <!-- 设定消息转换的编码为utf-8防止controller返回中文乱码 -->
 <bean
  class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
  <property name="messageConverters">
   <list>
    <bean
     class="org.springframework.http.converter.StringHttpMessageConverter">
     <property name="supportedMediaTypes">
      <list>
       <value>text/html;charset=UTF-8</value>
      </list>
     </property>
    </bean>
   </list>
  </property>
 </bean>
 <!-- 添加注解驱动 -->
 <mvc:annotation-driven />
 <!-- 默认扫描的包路径 -->
 <context:component-scan base-package="com.imooc.springquartz" />

 <!-- mvc:view-controller可以在不需要Controller处理request的情况,转向到设置的View -->
 <!-- 像下面这样设置,如果请求为/,则不通过controller,而直接解析为/index.jsp -->
 <mvc:view-controller path="/" view-name="index" />
 <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
  <property name="viewClass"
   value="org.springframework.web.servlet.view.JstlView"></property>
  <!-- 配置jsp路径前缀 -->
  <property name="prefix" value="/"></property>
  <!-- 配置URl后缀 -->
  <property name="suffix" value=".jsp"></property>
 </bean>
<!--配置类和方法-->
 <bean id="simpleJobDetail"
  class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
  <property name="targetObject" ref="myBean" />
  <property name="targetMethod" value="printMessage" />
 </bean>

 <bean id="firstComplexJobDetail"
  class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
  <property name="jobClass"
   value="com.imooc.springquartz.quartz.FirstScheduledJob" />
  <property name="jobDataMap">
   <map>
    <entry key="anotherBean" value-ref="anotherBean" />
   </map>
  </property>
  <property name="Durability" value="true"/>
 </bean>
 <!-- 距离当前时间1秒之后执行,之后每隔两秒钟执行一次 -->
 <bean id="mySimpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
     <property name="jobDetail" ref="simpleJobDetail"/>
     <property name="startDelay" value="1000"/>
     <property name="repeatInterval" value="2000"/>
 </bean>
 <!-- 每隔5秒钟执行一次 -->
 <bean id="myCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
     <property name="jobDetail" ref="firstComplexJobDetail"/>
     <property name="cronExpression" value="0/5 * * ? * *"/>
 </bean>
 <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
     <property name="jobDetails">
         <list>
             <ref bean="simpleJobDetail"/>
             <ref bean="firstComplexJobDetail"/>
         </list>
     </property>
     <property name="triggers">
         <list>
             <ref bean="mySimpleTrigger"/>
             <ref bean="myCronTrigger"/>
         </list>
     </property>
 </bean>
</beans>  

判断cron格式是否正确

CronExpression.isValidExpression(cron)

cron获取下次运行时间

 /**
  * 查看cron下次运行时间
  * @param cron
  */
 public Date getNextTime(String cron){
  //检查cron格式
  if (CronExpression.isValidExpression(cron)){//cron格式正确
   try {
    System.out.println(new CronExpression(cron).getNextValidTimeAfter(new Date()));
    return new CronExpression(cron).getNextValidTimeAfter(new Date());
   } catch (ParseException e) {
    e.printStackTrace();
    return null;
   }
  }else return null;
 }

来自为知笔记(Wiz)

附件列表

原文地址:https://www.cnblogs.com/ziyue7575/p/c588f366aa150677c73972604a979939.html

时间: 2024-10-10 16:57:57

Quartz定时基础的相关文章

Quartz定时任务调度机制解析(CronTirgger、SimpleTrigger )

一.Quartz的介绍 Quartz 是 OpenSymphony 开源组织在任务调度领域的一个开源项目,完全基于 Java 实现.该项目于 2009 年被 Terracotta 收购,目前是 Terracotta 旗下的一个项目.它是一个而安全有java辨析额的开源作业调度框架. 二.Quartz 具有以下特点 1.强大的调度功能,例如支持丰富多样的调度方法,可以满足各种常规及特殊需求: 2.灵活的应用方式,例如支持任务和调度的多种组合方式,支持调度数据的多种存储方式: 3.分布式和集群能力,

java 多线程——quartz 定时调度的例子

java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 java 多线程—— 线程等待与唤醒 概述 第1部分 配置 第2部分 代码示例 第1部分 配置 有关quartz的api文档地址:Quartz Enterprise Job Scheduler 1.8.6 API 主要接口目录: 重点看下Job,Scheduler,Trigger,JobDetai

Spring整合Quartz定时发送邮件

功能描述:刚开始接触Quartz,试着用Quartz整合spring实现每隔一分钟发送一封邮件连续发送10次 核心jar: 邮件发送:commons-email-1.2.jar mail.jar(必须的) quartz:quartz-all-1.8.3.jar quartz-all-1.8.3/lib/下所有jar spring:spring-context-support.ajr(必须的) 只贴出核心代码: Email发送:使用apache commons-email跟mail package

quartz定时

字段允许值允许的特殊字符 秒 0-59 , - * / 分 0-59 , - * / 小时 0-23 , - * / 日期 1-31 , - * ? / L W C 月份 1-12 或者 JAN-DEC , - * / 星期 1-7 或者 SUN-SAT , - * ? / L C # 年(可选)留空, 1970-2099 , - * / 表达式意义 "0 0 12 * * ?" 每天中午12点触发 "0 15 10 ? * *" 每天上午10:15触发 "

项目一:第十四天 1.在realm中动态授权 2.Shiro整合ehcache 缓存realm中授权信息 3.动态展示菜单数据 4.Quartz定时任务调度框架—Spring整合javamail发送邮件 5.基于poi实现分区导出

1 Shiro整合ehCache缓存授权信息 当需要进行权限校验时候:四种方式url拦截.注解.页面标签.代码级别,当需要验证权限会调用realm中的授权方法   Shiro框架内部整合好缓存管理器,整合ehcache环境,只需要配置即可.     <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache-core</artifactId> <version>

Spring+quartz集群配置,Spring定时任务集群,quartz定时任务集群

Spring+quartz集群配置,Spring定时任务集群,quartz定时任务集群 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 蕃薯耀 2016年7月7日 09:06:09 星期四 http://fanshuya

浅谈Quartz定时任务调度

原文:浅谈Quartz定时任务调度 一  开发概述 对于具有一定规模的大多数企业来说,存在着这样一种需求:存在某个或某些任务,需要系统定期,自动地执行,然而,对大多数企业来说,该技术的实现,却是他们面临的一大难点和挑战.  对于大部分企业来说,实现如上功能,挑战在哪里? 挑战一:如何做一个自动服务的系统? 是从0到1开发(费时费力花钱,还不一定开发成功,即使开发成功,也未必好用),还是购买第三方服务(花钱). 挑战二:如何实现复杂的"定期规则"? 对于简单的定期规则,可以借助于wind

quartz定时执行任务,并配置web.xml

零.废话: 离职四个多月,毕业办完之后6月13日又回到公司上班,一直有想法把自己学的东西记录整理分享做出来,一直没动过,今天开始第一篇,这是今天项目上需要做个定时任务,临时学的,quartz的功能还是很强大用起来也方便,这里的demo只是实现每天定时执行一次,其他功能可以在此基础上继续深入学习,哈哈 睡觉,明天继续. 一.maven依赖: <dependency> <groupId>org.quartz-scheduler</groupId> <artifactI

java sql编辑器 动态报表 数据库备份还原 quartz定时任务调度 自定义表单 java图片爬虫

获取[下载地址]   QQ: 313596790   [免费支持更新] 三大数据库 mysql  oracle  sqlsever   更专业.更强悍.适合不同用户群体 [新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统] A 集成代码生成器(开发利器)+快速构建表单;            QQ:313596790 freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本,处理类,service等完整模块 B 集成阿里巴巴数据库连接池druid;