科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道Java Web应用中的任务调度(2)

Java Web应用中的任务调度(2)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

 任务调度是大型J2EE web应用中常见的工作。开发者希望以指定的间隔时间执行各类操作,并完成一些无需用户输入的任务。Java中可有无数方法来做到这一点,但是在web应用中却并没有这方面的统一标准。

作者:Chris Hardin 来源:IT专家网 2008年5月5日

关键字: 调度 任务 web java

  • 评论
  • 分享微博
  • 分享邮件
配置过程的第二步是在web.xml中加入用来初始化Quartz servlet(org.quartz.ee.servlet.QuartzInitializerServlet)的内容,因为需要它将SchedulerFactory添加到ServletContext中,以便在我们的Struts插件中可以访问。SchedulerFactory就是我们在Struts插件中获得Scheduler对象的来源。除了struts-config.xml 和web.xml之外,还要在web应用的classes目录下放置一个quartz.properties文件。此文件的位置也可以在web.xml中作为QuartzInitializerServlet的启动参数来指定。

  <servlet>

     <servlet-name>QuartzInitializer</servlet-name>
     <display-name>Quartz Initializer Servlet</display-name>

  <servlet-class>
    org.quartz.ee.servlet.QuartzInitializerServlet
  </servlet-class>
  <load-on-startup>1</load-on-startup>
  <init-param>
    <param-name>shutdown-on-unload</param-name>
    <param-value>true</param-value>
  </init-param>

  <init-param>
    <param-name>start-scheduler-on-load</param-name>
    <param-value>false</param-value>
    </init-param>

 </servlet>

  这里其实完全可以不使用Struts和SchedulerPlugIn,但如果将来决定要以其它的任务调度框架替换Quartz的话,额外的抽象层就很有用了。长远看来,让一切保持松散耦合总会使工作变得容易些。如果你使用其它MVC框架,也可以用SchedulerPlugIn.init()方法中的代码达到同样的效果。此外,还可以用Servlet 2.3规范中的ServletContextListener来实现同样的初始化过程。

  到此为止web应用已配置完毕,我们可以创建一个.war文件并部署到服务器上,从控制台观察SchedulerPlugIn的输出信息。然而在此之前,让我们先看看如何向任务调度器提交一项任务。

  我们可以从web应用中的任何类访问SchedulerPlugIn的唯一实例,并调度一些要执行的工作。首先需要一个Trigger(触发器)对象来告诉任务何时运行、每隔多久运行一次。Quartz支持多种触发器,在这个例子中我们使用CronTrigger。

Trigger trigger = new CronTrigger("trigger1", "group1");
trigger.setCronExpression("0 0 15 ? * WED");

  以上的触发器会在每周三的下午3点执行指定任务。现在我们只要创建一个JobDetail对象,并把它和上面的触发器一起传递给SchedulerPlugIn的scheduleWork()方法。

    JobDetail jobDetail =
        new JobDetail("Hello World Job",
                      "Hello World Group",
                      HelloWorld.class,
                      true, true, true);   
//Schedule The work
//调度这项任务
    SchedulerPlugIn.scheduleWork(scheduledJobDetail, trigger);

  实际工作在何处?

  至此我们已决定Trigger,可以开始调度工作了。看上去一切都已完成,但实际上我们只是调度了一项任务,还有最重要的一步有待完成。注意HelloWorld.class作为参数传递给了JobDetail的构造函数。这个类就是实际完成工作的地方。HelloWorld继承了Quartz的Job类,并覆盖了execute()方法。当任务管理器决定运行这个任务时,execute()方法将被调用。来看代码:

import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;

//extend the proper Quartz class
//继承适当的Quartz类
public class HelloWorld extends Job {

//override the execute method
//覆盖execute方法
    public void execute(JobExecutionContext context) {

// Every job has it's own job detail
//每个Job都有独立的JobDetail
    JobDetail jobDetail = context.getJobDetail();
// The name is defined in the job definition
//name在Job定义中指定
    String jobName = jobDetail.getName();
//Every job has a Job Data map for storing extra information
//每个Job都有一个Job Data map来存放额外的信息
    JobDataMap dataMap = jobDetail.getJobDataMap();
      
       System.out.println("Hello World!!!");
   }
 }

出于测试的目的,你可能希望将触发器的频率调的高一点,以便观察到HelloWorld的动作。毕竟,你不想一直等到凌晨2点才能确定调度的任务确实运行了。相反,你可能需要一个每隔10秒运行的触发器:

Trigger trigger = new SimpleTrigger("trigger1", "group1");
trigger.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
trigger.setRepeatInterval(10000L); // milliseconds毫秒

  注意,这个触发器没有使用类cron的语法。Quartz有大量各类的选项和配置方法,可适用于任何任务调度的需要。

  其它计时方式的配置

  Quartz提供了多种调度任务的方式。CronTrigger可能是最复杂的一种,不过还有其它的选择。大多数触发器可以由Quartz提供的TriggerUtils类创建。以下是一些常见的触发器的例子。如谚语所言,条条大路通罗马!

  每天凌晨2:22触发的触发器

  // 方法一:使用makeDailyTrigger

Trigger trigger = TriggerUtils.makeDailyTrigger(2, 22);
trigger.setName("trigger1");
trigger.setGroup("group1");

  // 方法二:使用CronTrigger

Trigger trigger = new CronTrigger("trigger1", "group1");
trigger.setCronExpression("0 22 2 * * ?");

每5秒执行一次的触发器
/*  *
 * 方法一:makeSecondlyTrigger
 * 注意以下代码将创建一个立即启动的触发器。要控制启动时间,使用
 * trigger.setStartTime(Date)方法。
 */
Trigger trigger = TriggerUtils.makeSecondlyTrigger(5);
trigger.setName("MyFiveSecondTrigger");
trigger.setGroup("MyTriggerGroup");

 /*
 *
 * 方法二:设置SimpleTrigger的重复次数和间隔时间。
 * 注意以下代码将创建一个立即启动的触发器。要控制启动时间,使用
 * trigger.setStartTime(Date)方法。
 */
Trigger trigger = new SimpleTrigger("trigger1", "group1");
trigger.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
trigger.setRepeatInterval(5000L); // milliseconds

  按间隔时间运行任务

Trigger trigger = new SimpleTrigger("trigger1", "group1");
// 24 hours * 60(minutes per hour) *
// 60(seconds per minute) * 1000(milliseconds per second)
// 24小时 * 60(分钟每小时) * 60(秒每分钟)* 1000(毫秒每秒钟)
trigger.setRepeatInterval(24L * 60L * 60L * 1000L);

  结论

  在这个演示中,我们只接触了Quartz框架的一些初级功能。记住,Java 5 和J2EE 5也有自己的任务调度机制,但是它们不像Quartz那样灵活易用。Quartz是目前唯一的开源Java任务调度框架,它的确为开发者的锦囊中增加了很有用的内容。你可从Open Symphony下载Quartz,并得到一份很好的教程和使用说明。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章