当前位置: 首页 > 工具软件 > quartz web > 使用案例 >

Quartz的搭建和在Web中的使用

谢飞舟
2023-12-01

Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Quartz是一个完全由Java编写的开源作业调度框架,为在Java应用程序中进行作业调度提供了简单却强大的机制。Quartz允许开发人员根据时间间隔来调度作业。它实现了作业和触发器的多对多的关系,还能把多个作业与不同的触发器关联。

参考的优秀资料

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,配置线程池的容量,即表示同时最多可运行的线程数量。在生产环境,此参数应根据实际情况配置。quartz.properties的配置如下:

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>

任务的创建(带有回调参数)

import org.quartz.Job;
import org.quartz.JobDataMap;
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 context) throws JobExecutionException {
        // 接受参数
        JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
        // 通过这种方式,传递参数
        String taskId = jobDataMap.getString("taskId");

        // 此任务仅打印日志便于调试、观察
        this.logger.debug(this.getClass().getName() + " trigger..." + taskId);
    }

}

简单定时任务的创建

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 BootstrapSimple {
    private static Logger logger = LoggerFactory.getLogger(BootstrapSimple.class);

    public static void main(String[] args) {

        try {
            // 获取Scheduler实例
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

            // 具体任务
            JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build();
            // 在任务回调的时候,获取传递的参数,在任务回调的时候,完成想要的操作
            job.getJobDataMap().put("taskId", "I am Hello Job ...");

            // 触发时间点
            SimpleScheduleBuilder simpleScheduleBuilder = SimpleScheduleBuilder.simpleSchedule()//
                    .withIntervalInSeconds(5)//
                    .repeatForever();//
            Trigger trigger = TriggerBuilder.newTrigger()//
                    .withIdentity("trigger1", "group1")//
                    .withSchedule(simpleScheduleBuilder).build();//

            // 交由Scheduler安排触发
            scheduler.scheduleJob(job, trigger);

            // 启动调度器
            scheduler.start();

            /* 为观察程序运行,此设置主程序睡眠3分钟才继续往下运行(因下一个步骤是“关闭Scheduler”) */
            try {
                TimeUnit.MINUTES.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            // 关闭Scheduler
            scheduler.shutdown();

        } catch (SchedulerException se) {
            logger.error(se.getMessage(), se);
        }
    }

}

常用的Cron Schedule

import java.util.concurrent.TimeUnit;

import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class BootstrapCorn {
    private static Logger logger = LoggerFactory.getLogger(BootstrapCorn.class);

    public static void main(String[] args) {

        try {
            // 获取Scheduler实例
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

            // 具体任务
            JobDetail job = JobBuilder.newJob(HelloJob.class)//
                    .withIdentity("job1", "group1").build();
            //传递参数,一边在回调任务的时候,完成相应的操作
            job.getJobDataMap().put("taskId", "I am Hello Job ...");

            // 表达式的支持
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/2 * * * * ?");
            Trigger trigger = TriggerBuilder.newTrigger()//
                    .withIdentity("trigger1", "group1")//
                    .withSchedule(cronScheduleBuilder).build();//

            // 交由Scheduler安排触发
            scheduler.scheduleJob(job, trigger);

            // 启动调度器
            scheduler.start();

            /* 为观察程序运行,此设置主程序睡眠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类与上例子相同,这里只是注册定时任务的地方换成此监听器了。

定时任务监听器(用于注册定时任务)

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);
        }
    }

}

在web.xml中,加入自定义的监听器

<listener>
  <listener-class>myuartz.ApplicationContextListener</listener-class>
</listener>

参考的博文地址

http://www.cnblogs.com/nick-huang/p/4848843.html#_label0
 类似资料: