• Spring Quartz实现任务调度


    任务调度

    在企业级应用中,经常会制定一些“计划任务”,即在某个时间点做某件事情 核心是以时间为关注点,即在一个特定的时间点,系统执行指定的一个操作 任务调度涉及多线程并发、线程池维护、运行时间规则解析、运行现场的保护以恢复等方面 Quartz框架是一个开源的企业级任务调度服务,已经被作为任务调度的良好解决方案.

    Quartz框架核心

    Quartz对任务调度进行了高度抽象,提出了3个核心概念,并在org.quartz包中通过接口和类进行了描述

    任务:就是执行的工作内容。Quartz提供Job接口来支持任务定义

    触发器:定义触发Job执行的时间触发规则。Quartz提供Trigger类及其子类支持触发器功能

    调度器:Quartz提供了Scheduler接口,将工作任务触发器绑定,保证任务可以在正确的时间执行

    运行环境

    任务调度

    任务执行

    任务持久化

    事务

    集群

    监听器和插进

    Quartz案例

    1.找到Quartz框架的jar包

    2.开始创建entity实体层定义任务的模板

    package cn.entity;
    
    public class Plan {
          //时间
        private String date;
        //任务
        private String task;
        
        public Plan() {
            super();
        }
        
        public Plan(String date, String task) {
            super();
            this.date = date;
            this.task = task;
        }
    
        @Override
        public String toString() {
            return "Plan [date=" + date + ", task=" + task + "]";
        }
        public String getDate() {
            return date;
        }
        public void setDate(String date) {
            this.date = date;
        }
        public String getTask() {
            return task;
        }
        public void setTask(String task) {
            this.task = task;
        }
        
    }

    3.定制一个泛型集合用户存储多个Plan对象,提供一个方法读取该泛型集合中的data

    package cn.service;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import cn.entity.Plan;
    /**
     * 提醒服务类
     * @author 景佩佩
     *
     */
    public class RemindService {
         //01.创建一个集合,并且方法返回值是一个集合类型
        public List<Plan> getPlansForToday(){
            List<Plan> list=new ArrayList<Plan>();
            Plan plan1=new Plan("2016年12月16日","2016最后一个月");
            Plan plan2=new Plan("2016年12月18日","Quartz");
            
            list.add(plan1);
            list.add(plan2);
            
            return list;
        }
        
        
        //02.用来打印集合中提醒内容的方法
        public void printMessage(){
            List<Plan> list = getPlansForToday();
            for (Plan plan : list) {
                //单个的plan
                System.out.println("计划的时间"+plan.getDate()+"	计划内容"+plan.getTask());
            }
        }
    }

    4.提醒业务类

    package cn.quartz;
    
    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    
    import cn.service.RemindService;
    /**
     * 提醒业务
     * @author 景佩佩
     *
     */
    //让一个普通类变成计划
    public class RemindJob implements Job {
        //植入service 对象
        private RemindService service=new RemindService();
        @Override
        public void execute(JobExecutionContext context) throws JobExecutionException {
            service.printMessage();
        }
        public RemindService getService() {
            return service;
        }
        public void setService(RemindService service) {
            this.service = service;
        }
    
        
    }

    Job接口中只有一个 execute()方法,在实现类中 实现该方法以执行具体任务。   

    5.真正的任务对象和触发器对象

    package cn.test;
    
    import java.util.Date;
    
    import org.quartz.CronScheduleBuilder;
    import org.quartz.CronTrigger;
    import org.quartz.DateBuilder;
    import org.quartz.JobBuilder;
    import org.quartz.JobDetail;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerException;
    import org.quartz.SchedulerFactory;
    import org.quartz.SimpleScheduleBuilder;
    import org.quartz.Trigger;
    import org.quartz.TriggerBuilder;
    import org.quartz.TriggerKey;
    import org.quartz.impl.StdSchedulerFactory;
    
    import cn.quartz.RemindJob;
    
    public class MyQuartzTest {
        
        public static void tool() throws SchedulerException, InterruptedException{
            //第一步构建Job
             JobDetail job = JobBuilder.newJob(RemindJob.class)//
                     .withIdentity("job1", "group1")//
                     .build();
             
             //第二步创建Trigger
             //第一种方式  控制不太好
            /* Date runTime = DateBuilder.evenMinuteDate(new Date(System.currentTimeMillis()));
             Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")//
                     .startAt(runTime).build();*/
             
             //第二种方式  不太好
             /*Trigger trigger = TriggerBuilder.newTrigger() 
                     .withIdentity(TriggerKey.triggerKey("myTrigger", "myTriggerGroup"))
                     .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                         .withIntervalInSeconds(2)
                         .repeatForever())
                     .startAt(new Date(System.currentTimeMillis()+2000))
                     .build();*/
             
                     
             
                //第三步绑定  JOb和Trigger
               // First we must get a reference to a scheduler
               //创建调度者工厂
                SchedulerFactory sf = new StdSchedulerFactory();
              //创建一个调度者
                Scheduler sched = sf.getScheduler();
              //注册并进行调度
                sched.scheduleJob(job, trigger);
              //启动调度
                sched.start();
                /*Thread.sleep(3000);
                 * //关闭调度
                sched.shutdown();*/
        }
    
        
            
        public static void main(String[] args) throws SchedulerException, InterruptedException {
            tool();
            System.out.println("呵呵");
        }
    }

     第一种方式:

    第二种方式:

    6.使用CronTrigger

    CronTrigger也是Trigger的子类

    CronTrigger和SimpleTrigger的对

    CronTrigger允许用户更精准地控制任务的运行日期和时间,而不仅仅是定义工作的频度

    CronTrigger通过Cron表达式定义准确的运行时间点。创建CronTrigger的语法如下:

    7.Cron表达式

    要使用CronTrigger,必须掌握Cron表达式

    Cron表达式由6~7个由空格分隔的时间元素组成。第7个元素可选

    Cron表达式的每个字段,都可以显式地规定一个值(如49)、一个范围(如1-6)、一个列表(如1,3,5)或者一个通配符(如*)

    8.Cron表达式有几个特殊的字符,说明如下

    “ - ”:中划线,表示一个范围

    “ , ”:使用逗号间隔的数据,表示一个列表

    “ * ”:表示每一个值,它可以用于所有字段。例如:在小时字段表示每小时

    “ ? ”:该字符仅用于“月份中的哪一天”字段和“星期几”字段,表示不指定值

    “ / ”:通常表示为x/y,x为起始值,y表示值的增量。

    “ L ”:表示最后一天,仅在日期和星期字段中使用

    “ # ”:只能用于“星期几”字段,表示这个月的第几个周几。例如:“6#3”指这个月第三个周五

    9.Cron表达式案例

     

    测试:

    package cn.test;
    
    import java.util.Date;
    
    import org.quartz.CronScheduleBuilder;
    import org.quartz.CronTrigger;
    import org.quartz.DateBuilder;
    import org.quartz.JobBuilder;
    import org.quartz.JobDetail;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerException;
    import org.quartz.SchedulerFactory;
    import org.quartz.SimpleScheduleBuilder;
    import org.quartz.Trigger;
    import org.quartz.TriggerBuilder;
    import org.quartz.TriggerKey;
    import org.quartz.impl.StdSchedulerFactory;
    
    import cn.quartz.RemindJob;
    
    public class MyQuartzTest {
        
        public static void tool() throws SchedulerException, InterruptedException{
            //第一步构建Job
             JobDetail job = JobBuilder.newJob(RemindJob.class)//
                     .withIdentity("job1", "group1")//
                     .build();
             
             //第二步创建Trigger
            /**
             * 2016年每月的第三个星期六上午10:18触发 0 18 10 ? * 6#3 2016
             */
            CronTrigger trigger=TriggerBuilder.newTrigger()//
                    .withIdentity("myTrigger", "myTriggerGroup")//
                    .withSchedule(CronScheduleBuilder.//
                            cronSchedule("0 18 10 ? * 6#3 2016")).build();
             
             
                //第三步绑定  JOb和Trigger
               // First we must get a reference to a scheduler
               //创建调度者工厂
                SchedulerFactory sf = new StdSchedulerFactory();
              //创建一个调度者
                Scheduler sched = sf.getScheduler();
              //注册并进行调度
                sched.scheduleJob(job, trigger);
              //启动调度
                sched.start();
                  }
    
        
            
        public static void main(String[] args) throws SchedulerException, InterruptedException {
            tool();
            System.out.println("呵呵");
        }
    }

  • 相关阅读:
    bug-- java.lang.RuntimeException: Type “Klass*"
    ThreadPoolExecutor源码分析二
    ThreadPoolExecutor源码分析一
    java动态代理框架
    liunx 中一个命令可以检测 ps -C java --no-heading| wc -l 一般用于shell脚步编写用
    log4j.properties 使用说明
    图文详解MyEclipse中新建Maven webapp项目的步骤(很详细)
    MySQL高可用性之Keepalived+Mysql(双主热备)
    使用cglib动态创建类,添加方法
    2017年5月5日 星红桉liunx动手实践mysql 主主双机热备
  • 原文地址:https://www.cnblogs.com/jingpeipei/p/6193906.html
Copyright © 2020-2023  润新知