zoukankan      html  css  js  c++  java
  • 【Quartz】Quartz的搭建、应用(单独使用Quartz)

    阅读目录

    Quartz在Java构建的系统中,是十分常用的定时任务框架。

    本文,记录、介绍Quartz的简单入门的单独搭建(此文入门学习Quartz为主,并非基于Spring托管形式)。

    > 参考的优秀资料

    Quartz Quick Start Guide

    Chapter 3: Logback configuration

    > 版本说明

    除了Quartz,还引入logback(为了看详细的日志嘛!)

    <dependencies>
            <dependency>
                <groupId>org.quartz-scheduler</groupId>
                <artifactId>quartz</artifactId>
                <version>2.2.0</version>
            </dependency>
    
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
                <version>1.1.0</version>
            </dependency>
        </dependencies>
    

      

    > 简单的搭建

    jar包的引入参考上述的pom文件。

    quartz.properties,配置quartz的设置。

    ,org.quartz.threadPool.threadCount,配置线程池的容量,即表示同时最多可运行的线程数量。在生产环境,此参数应根据实际情况配置。

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

      logback.xml,日志框架logback的配置。这里只简单地配置了控制台和日志文件的输出哦(>_<)

    <configuration>
    
        <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
            <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder 
                by default -->
            <encoder>
                <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
                </pattern>
            </encoder>
        </appender>
    
        <appender name="FILE" class="ch.qos.logback.core.FileAppender">
            <file>D:/logs/quartz_task_application.log</file>
            <encoder>
                <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
                </pattern>
            </encoder>
        </appender>
    
        <root level="debug">
            <appender-ref ref="STDOUT" />
            <appender-ref ref="FILE" />
        </root>
    
    </configuration>
    

      HelloJob.java,具体执行的任务

    package No01简单的定时任务;
    
    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class HelloJob implements Job {
        
        Logger logger = LoggerFactory.getLogger(this.getClass());
    
        @Override
        public void execute(JobExecutionContext arg0) throws JobExecutionException {
            // 此任务仅打印日志便于调试、观察
            this.logger.debug(this.getClass().getName() + " trigger...");
        }
    
    }
    

      那么,在哪里定义“在什么时候执行什么任务呢?”

    package No01简单的定时任务;
    
    import java.util.concurrent.TimeUnit;
    
    import org.quartz.JobBuilder;
    import org.quartz.JobDetail;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerException;
    import org.quartz.SimpleScheduleBuilder;
    import org.quartz.Trigger;
    import org.quartz.TriggerBuilder;
    import org.quartz.impl.StdSchedulerFactory;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    
    public class Bootstrap {
        private static Logger logger = LoggerFactory.getLogger(Bootstrap.class);
    
        public static void main(String[] args) {
    
            try {
                // 获取Scheduler实例
                Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
                scheduler.start();
    
                // 具体任务
                JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build();
    
                // 触发时间点
                SimpleScheduleBuilder simpleScheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
                        .withIntervalInSeconds(5).repeatForever();
                Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")
                        .startNow().withSchedule(simpleScheduleBuilder).build();
    
                // 交由Scheduler安排触发
                scheduler.scheduleJob(job, trigger);
                
                /* 为观察程序运行,此设置主程序睡眠3分钟才继续往下运行(因下一个步骤是“关闭Scheduler”) */
                try {
                    TimeUnit.MINUTES.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
                // 关闭Scheduler
                scheduler.shutdown();
    
            } catch (SchedulerException se) {
                logger.error(se.getMessage(), se);
            }
        }
    
    }
    

      

    > 在Web应用中使用Quartz

    Quartz也常用在Web应用中,常见的是交由Spring托管的形式,但这里并非介绍这个。这里介绍Quartz在Web应用中单独使用。

    一般来说,Web应用启动时,应注册已经确定的定时任务;一些动态的、未确定触发时间的定时任务,后续可通过静态的Scheduler注册。

    这里使用监听器在应用启动时注册,记得在web.xml注册这个监听器哦(>_<);在关闭Web应用时,也要相应的注销定时任务。

    其他配置文件、Java类与上例子相同,这里只是注册定时任务的地方换成此监听器了。

    package No02Web应用使用Quartz;
    
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    
    import org.quartz.JobBuilder;
    import org.quartz.JobDetail;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerException;
    import org.quartz.SimpleScheduleBuilder;
    import org.quartz.Trigger;
    import org.quartz.TriggerBuilder;
    import org.quartz.impl.StdSchedulerFactory;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import No01简单的定时任务.HelloJob;
    
    /**
     * Application Lifecycle Listener implementation class AListener
     *
     */
    public class ApplicationContextListener implements ServletContextListener {
        
        private Logger logger = LoggerFactory.getLogger(this.getClass());
        
        public static Scheduler scheduler = null;
    
        @Override
        public void contextInitialized(ServletContextEvent arg0) {
            this.logger.info("The application start...");
            
            /* 注册定时任务 */
            try {
                // 获取Scheduler实例
                scheduler = StdSchedulerFactory.getDefaultScheduler();
                scheduler.start();
    
                // 具体任务
                JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build();
    
                // 触发时间点
                SimpleScheduleBuilder simpleScheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
                        .withIntervalInSeconds(5).repeatForever();
                Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")
                        .startNow().withSchedule(simpleScheduleBuilder).build();
    
                // 交由Scheduler安排触发
                scheduler.scheduleJob(job, trigger);
                
                this.logger.info("The scheduler register...");
            } catch (SchedulerException se) {
                logger.error(se.getMessage(), se);
            }
        }
        
        @Override
        public void contextDestroyed(ServletContextEvent arg0) {
            this.logger.info("The application stop...");
            
            /* 注销定时任务 */
            try {
                // 关闭Scheduler
                scheduler.shutdown();
                
                this.logger.info("The scheduler shutdown...");
            } catch (SchedulerException se) {
                logger.error(se.getMessage(), se);
            }
        }
    
    }
    

      

    <listener>
            <listener-class>No02Web应用使用Quartz.ApplicationContextListener</listener-class>
        </listener>
    

      ,如果你在Eclipse中调试,可能发现无法看到contextDestroyed方法的执行,请注意用Stop方式(图一)关闭应用,而不是Terminate(图二)。

    图一

    图二

    > 常用的Cron Schedule

    相对于其他方式定义定时任务的触发时间,我们较常用Cron Schedule,小伙伴们也是吧?

    Cron Schedule的使用

    // 具体任务
    JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build();
    
    // 触发时间点
    CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0 * * * * ? *");
    Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")
            .withSchedule(cronScheduleBuilder).build();
    
    // 交由Scheduler安排触发
    scheduler.scheduleJob(job, trigger);
    

      

    而Cron Expression的学习可参考下列优秀的文章:

    Tutorial - Lesson 6: CronTrigger

    Spring - Quartz - cronExpression中问号(?)的解释

    作者:Nick Huang 博客:http://www.cnblogs.com/nick-huang/ 本博文为学习、笔记之用,以笔记记录作者学习的知识与学习后的思考或感悟。学习过程可能参考各种资料,如觉文中表述过分引用,请务必告知,以便迅速处理。如有错漏,不吝赐教。
  • 相关阅读:
    C++类内存分布
    职场人理财之指数基金篇
    职场之殇---有些事情千万不能做
    职场人为什么需要理财
    职场发展之跟对老板有多重要
    职场中怎么做好一个演讲
    多线程如何按指定顺序同步执行
    多线程抢票系统浅析
    Spring Boot进阶系列三
    Spring Boot进阶系列二
  • 原文地址:https://www.cnblogs.com/beautiful-code/p/5749788.html
Copyright © 2011-2022 走看看