zoukankan      html  css  js  c++  java
  • quartz的学习和简单使用

    以前在框架中使用过,很多都是纯粹的复制粘贴,了解过用法知道如何配置,但时间久了就没什么印象了,现在重新捡起来,再次进行学习。

    quartz相关的介绍都已经很多了,我就不重复啰嗦,简单说一下个人的认识和使用。

    * 定时任务 quartz的设计比较合理,将调度Scheduler、触发Trigger、任务进行分离Job(这里使用JobDetail创建Job的实例)
    * 调度Scheduler负责任务的调度执行以及任务的销毁
    * 触发器设定Trigger事件的触发条件或时间,分为SimpleTrigger和CronTrigger两种常用模式,
    * 当然还有其他两种模式CalendarIntervalTrigger 按日期触发的Trigger 和 DailyTimeIntervalTrigger 按天触发的Trigger
    * 其中CronTrigger中的设置规范基本等同于cron4j,不过增加了秒
    * JobDetail是任务的定义,而Job是任务的执行逻辑

    在学习cron4j的时候,我使用了的内部类,在创建quartz的时候我也同样使用了内部类,但示例始终不能启动,找了很长时间,没想到这里还有个坑,现在也不知道因为什么。

    下面代码是个反面教材,是不能运行的,需要将HelloTask类单独出来写才可以运行。

    import java.util.Date;
    
    import org.quartz.Job;
    import org.quartz.JobDetail;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerException;
    import org.quartz.SchedulerFactory;
    import org.quartz.Trigger;
    import org.quartz.impl.StdSchedulerFactory;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import static org.quartz.JobBuilder.newJob;
    import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
    import static org.quartz.TriggerBuilder.newTrigger;
    import static org.quartz.DateBuilder.evenMinuteDate ;  
    
    /**
     * 
     * @author Uboobo
     * 
     * 定时任务 quartz的设计比较合理,将调度Scheduler、触发Trigger、任务进行分离Job(这里使用JobDetail创建Job的实例)
     * 调度Scheduler负责任务的调度执行以及任务的销毁
     * 触发器设定Trigger事件的触发条件或时间,分为SimpleTrigger和CronTrigger两种常用模式,
     * 当然还有其他两种模式CalendarIntervalTrigger 按日期触发的Trigger 和 DailyTimeIntervalTrigger 按天触发的Trigger
     * 其中CronTrigger中的设置规范基本等同于cron4j,增加了秒
     * JobDetail是任务的定义,而Job是任务的执行逻辑
     *
     */
    
    public class QuartzTask
    {
        // 创建scheduler
        public static void createScheduler(JobDetail job, Trigger trigger)
        {
        try
        {
            // 创建scheduler,需要捕获调度异常
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
    
            // 加入这个调度
            scheduler.scheduleJob(job, trigger);
    
            // 启动之
            scheduler.start();
    
            // 运行一段时间后关闭
            Thread.sleep(10000);
    
            scheduler.shutdown(true);
    
        } catch (SchedulerException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InterruptedException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        }
    
        // 创建Trigger
        public static Trigger createTrigger()
        {
        Trigger trigger = newTrigger()
            .withIdentity("myTrigger", "group1")
            .startNow()
            .withSchedule(simpleSchedule()
                .withIntervalInSeconds(10)//间隔时间是10s
                .repeatForever())
            .build();
    
        return trigger;
        }
    
        // 创建Job
        public static JobDetail createJob()
        {
        JobDetail job = newJob(HelloTask.class)
            .withIdentity("myJob", "group1")
            .build();
        return job;
        }
    
        // 内部类 ,坑在这这里,需要使用单独的类
        static class HelloTask implements Job
        {
    
        @Override
        public void execute(JobExecutionContext context) throws JobExecutionException
        {
            JobDetail detail = context.getJobDetail();
            // TODO Auto-generated method stub
            String name = detail.getJobDataMap().getString("name");
    
            System.out.println(" my job do..." + name);
        }
    
        }
        public static void main(String[] args) throws Exception {  
          
        JobDetail job = createJob();
        Trigger trigger = createTrigger();
        createScheduler(job,trigger);
          
        } 

    代码里没有标注太多注释,这里多说几句,一个quartz任务要执行的话,首先要通过StdSchedulerFactory.getDefaultScheduler() 创建scheduler,只有这样才能使用调度,然后要通过Trigger去创建一个或多个触发器并设定执行时间,然后再去使用JobDetail创建job,再使用job去加载我们要去执行的类,最后使用调度去加载执行。

    quartz的设计将其进行分层还是有很多好处,但也增加了一些复杂度,如果直接使用scheduler去调用job也是可以的,但如果实现多重负责设置就比较困难了。

    下面贴一下可以运行的代码

        public static void main(String [] args)
        {
        try
        {
            // 创建scheduler
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
    
            // 定义一个Trigger
            Trigger trigger = newTrigger().withIdentity("trigger1", "group1") // 定义name/group
                .startNow()// 一旦加入scheduler,立即生效
                .withSchedule(simpleSchedule() // 使用SimpleTrigger
                        .withIntervalInSeconds(1) // 每隔一秒执行一次
                        .repeatForever()) // 一直执行,奔腾到老不停歇
                .build();
    
            // 定义一个JobDetail
            JobDetail job = newJob(HelloJob.class) // 定义Job类为HelloQuartz类,这是真正的执行逻辑所在
                .withIdentity("job1", "group1") // 定义name/group
                .usingJobData("name", "quartz") // 定义属性
                .build();
    
            // 加入这个调度
            scheduler.scheduleJob(job, trigger);
    
            // 启动之
            scheduler.start();
    
            // 运行一段时间后关闭
            Thread.sleep(100000);
            scheduler.shutdown(true);
            
        } catch (Exception e)
        {
            e.printStackTrace();
        }
        }
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    
    /** 
     * hello world Quartz 
     * @author weeks 
     * 
     */
    public class HelloJob implements Job
    {
    
        private static Logger _log = LoggerFactory.getLogger(HelloJob.class);
    
        /** 
         * Job,Job需要一个公有的构造函数,否则Factory无法构建 
         */
        public HelloJob()
        {
        }
    
        /** 
         * 实现execute方法 
         */
        public void execute(JobExecutionContext context) throws JobExecutionException
        {
        System.out.println(" my job do...");
        }
    }

    这里还遗留一个问题,import中使用了 static 有点不太明白,设计者为什么要这么做,这么做有什么好处,待我了解之后再来补充。

  • 相关阅读:
    冲印数码照片的奥秘
    买手机(一)
    情人节的考验
    一日三茶
    追寻童年的乐趣在PSP上玩童年玩过的街机游戏
    转贴:常用的美国俚语
    用左手画CAD
    桃花朵朵开春游南汇桃花节
    不用GPRS照样用手机上网以后手机费不能报销的朋友们也能用手机上网啦!
    双休日去爬山
  • 原文地址:https://www.cnblogs.com/shej123/p/10254301.html
Copyright © 2011-2022 走看看