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/ 本博文为学习、笔记之用,以笔记记录作者学习的知识与学习后的思考或感悟。学习过程可能参考各种资料,如觉文中表述过分引用,请务必告知,以便迅速处理。如有错漏,不吝赐教。
  • 相关阅读:
    Ubuntu 14.04 卸载通过源码安装的库
    Ubuntu 14.04 indigo 相关依赖
    Ubuntu 14.04 indigo 安装 cartographer 1.0.0
    Ubuntu 14.04 改变文件或者文件夹的拥有者
    安装cartographer遇到Unrecognized syntax identifier "proto3". This parser only recognizes "proto2"问题
    Unrecognized syntax identifier "proto3". This parser only recognizes "proto2". ”问题解决方法
    查看所有用户组,用户名
    1卸载ROS
    Ubuntu14.04 软件安装卸载
    Ubuntu14.04系统显示器不自动休眠修改
  • 原文地址:https://www.cnblogs.com/beautiful-code/p/5749788.html
Copyright © 2011-2022 走看看