Quartz入门使用

做个小结。

1. 基本配置

官网上有quartz的所有版本,下一个,把quartz-all-*.jar(根据需要)添加到lib目录中,在classpath目录添加quartz.properties属性文件,接下来你就可以进行开发了。
这是quartz.properties的基本配置。

Java代码
 
#============================================================================  
# Configure Main Scheduler Properties    
#============================================================================  
 
org.quartz.scheduler.instanceName = TestScheduler  
org.quartz.scheduler.instanceId = AUTO  
 
#============================================================================  
# Configure ThreadPool    
#============================================================================  
 
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool  
org.quartz.threadPool.threadCount = 3 
org.quartz.threadPool.threadPriority = 5 
 
#============================================================================  
# Configure JobStore    
#============================================================================  
 
org.quartz.jobStore.misfireThreshold = 60000 
 
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore 
#============================================================================
# Configure Main Scheduler Properties 
#============================================================================

org.quartz.scheduler.instanceName = TestScheduler
org.quartz.scheduler.instanceId = AUTO

#============================================================================
# Configure ThreadPool 
#============================================================================

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 3
org.quartz.threadPool.threadPriority = 5

#============================================================================
# Configure JobStore 
#============================================================================

org.quartz.jobStore.misfireThreshold = 60000

org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

 


2. web基本应用

quartz在web项目中有多种应用方式,和项目使用的其他技术也有关系。

添加一个servlet,将它配置到web.xml中:


Java代码
<servlet>  
        <servlet-name>QuartzStartupServlet</servlet-name>  
        <servlet-class>com.StartupServlet</servlet-class>  
        <load-on-startup>1</load-on-startup>  
</servlet> 
<servlet>
  <servlet-name>QuartzStartupServlet</servlet-name>
  <servlet-class>com.StartupServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

 

这样你就可以在这个servlet中,在服务器加载的时候同时加载定时任务:


Java代码
public void init(ServletConfig cfg) throws javax.servlet.ServletException  
    {  
        log.info("server start!");  
        initScheduler(cfg);  
    }  
 
    protected void initScheduler(ServletConfig cfg)  
    {  
        try 
        {  
            SchedulerFactory sf = new StdSchedulerFactory();  
            Scheduler scheduler = sf.getScheduler();  
            SimpleExample simpleExample = new SimpleExample(scheduler);  
            simpleExample.run();  
        } catch (Exception e)  
        {  
            log.error(e);  
        }  
    } 
public void init(ServletConfig cfg) throws javax.servlet.ServletException
 {
  log.info("server start!");
  initScheduler(cfg);
 }

 protected void initScheduler(ServletConfig cfg)
 {
  try
  {
   SchedulerFactory sf = new StdSchedulerFactory();
   Scheduler scheduler = sf.getScheduler();
   SimpleExample simpleExample = new SimpleExample(scheduler);
   simpleExample.run();
  } catch (Exception e)
  {
   log.error(e);
  }
 }

 

任务定义和加载在quartz的示例中有,这里不多费口舌了。

3. xml形式的任务配置

xml形式的应用,需要使用quartz的xml支持插件,只需有实现Job接口的任务就可以;这时需要在web.xml中添加默认的servlet配置:


Java代码
<servlet>  
        <display-name>Quartz Initializer Servlet</display-name>  
        <servlet-name>QuartzInitializer</servlet-name>  
        <servlet-class>  
            org.quartz.ee.servlet.QuartzInitializerServlet  
        </servlet-class>  
        <load-on-startup>1</load-on-startup>  
    </servlet> 
<servlet>
  <display-name>Quartz Initializer Servlet</display-name>
  <servlet-name>QuartzInitializer</servlet-name>
  <servlet-class>
   org.quartz.ee.servlet.QuartzInitializerServlet
  </servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>

 

在quartz.properties中添加xml配置需要的参数:


Java代码
#============================================================================  
# Configure Plugins   
#============================================================================  
 
org.quartz.plugin.triggHistory.class = org.quartz.plugins.history.LoggingJobHistoryPlugin  
 
org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.JobInitializationPlugin  
org.quartz.plugin.jobInitializer.fileNames = jobs.xml  
org.quartz.plugin.jobInitializer.overWriteExistingJobs = true 
org.quartz.plugin.jobInitializer.failOnFileNotFound = true 
org.quartz.plugin.jobInitializer.scanInterval = 10 
org.quartz.plugin.jobInitializer.wrapInUserTransaction = false 
#============================================================================
# Configure Plugins
#============================================================================

org.quartz.plugin.triggHistory.class = org.quartz.plugins.history.LoggingJobHistoryPlugin

org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.JobInitializationPlugin
org.quartz.plugin.jobInitializer.fileNames = jobs.xml
org.quartz.plugin.jobInitializer.overWriteExistingJobs = true
org.quartz.plugin.jobInitializer.failOnFileNotFound = true
org.quartz.plugin.jobInitializer.scanInterval = 10
org.quartz.plugin.jobInitializer.wrapInUserTransaction = false

上面配置中的fileNames是指向的classpath根目录。

在xml文件中定义任务名称和触发器,例如:
Java代码
<?xml version="1.0" encoding="UTF-8"?>  
<quartz>  
    <job>  
        <job-detail>  
            <name>dailybalance</name>  
            <group>balance</group>  
            <job-class>com.SimpleJob</job-class>  
        </job-detail>  
        <trigger>  
            <cron>  
                <name>dailybalancetrigger</name>  
                <group>balance</group>  
                <job-name>dailybalance</job-name>  
                <job-group>balance</job-group>  
                <cron-expression>0/50 * * * * ?</cron-expression>  
            </cron>  
        </trigger>  
    </job>  
</quartz> 
<?xml version="1.0" encoding="UTF-8"?>
<quartz>
 <job>
  <job-detail>
   <name>dailybalance</name>
   <group>balance</group>
   <job-class>com.SimpleJob</job-class>
  </job-detail>
  <trigger>
   <cron>
    <name>dailybalancetrigger</name>
    <group>balance</group>
    <job-name>dailybalance</job-name>
    <job-group>balance</job-group>
    <cron-expression>0/50 * * * * ?</cron-expression>
   </cron>
  </trigger>
 </job>
</quartz>


这样就OK了!几种配置可以同时应用,不会冲突!

4. quartz的动态时间管理

有时需要在不停止web服务的情况下修改任务的执行时间格式,网上的资料大多是在使用spring框架支持时如何动态管理时间格式的介绍。在使用spring支持时可以,不使用spring时更加简单

动态时间管理的关键是要共享调度管理器对象Scheduler,我们可以在最初加载任务调度的时候将它添加到servlet上下文中。

Java代码
SchedulerFactory sf = new StdSchedulerFactory();  
Scheduler scheduler = sf.getScheduler();  
......  
......  
cfg.getServletContext().setAttribute(SCHEDULER_KEY, scheduler);  
scheduler.start(); 
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler scheduler = sf.getScheduler();
......
......
cfg.getServletContext().setAttribute(SCHEDULER_KEY, scheduler);
scheduler.start();


这样,我们就可以在需要修改时间格式的地方使用了!下面的ctt变量就是一个ServletContext对象。通过Scheduler 的getTrigger方法取到触发器,用触发器对象的getCronExpression方法

可以获得时间格式。之后你可以另外创建一个同名的触发器,也可以修改现有触发器,再让调度管理器重新加载到内存就可以了!

Java代码
/** 
     * reset quartz job time 
     */ 
    public void reSetLotteryLoseBiddingTime(int lotteryType, Date date)  
    {  
        scheduler = (Scheduler) this.ctt.getAttribute(TIMING_WORK_SCHEDULER);  
        try 
        {  
            String lotteryName = "";  
            switch (lotteryType)  
            {  
            case 1://  
                lotteryName = "ssq";  
                break;  
            case 2://   
            {  
                lotteryName = "3D";  
            }  
                break;  
            case 3://   
            {  
                lotteryName = "qlc";  
            }  
                break;  
            case 4://   
            {  
                lotteryName = "23x5";  
            }  
                break;  
            default:  
                break;  
            }  
 
            loseBiddingJob = scheduler.getJobDetail("loseBiddingJob_" + lotteryName, "loseBiddingGroup");  
            loseBiddingTrigger = (CronTrigger) scheduler.getTrigger("loseBiddingTrigger_" + lotteryName,  
                    "loseBiddingGroup");  
            String time = loseBiddingTrigger.getCronExpression();  
            if (!time.equals(this.timeFormat(date)))  
            {  
                loseBiddingTrigger = new CronTrigger("loseBiddingTrigger_" + lotteryName, "loseBiddingGroup",  
                        "loseBiddingJob_" + lotteryName, "loseBiddingGroup", this.timeFormat(date));  
                Date ft = scheduler.rescheduleJob("loseBiddingTrigger_" + lotteryName, "loseBiddingGroup",  
                        loseBiddingTrigger);  
                log.info(loseBiddingJob.getFullName() + " has been scheduled to run at: " + ft  
                        + " and excute based on expression: " + loseBiddingTrigger.getCronExpression());  
            }  
        } catch (Exception e)  
        {  
            log.error(e);  
        }  
    } 
/**
  * reset quartz job time
  */
 public void reSetLotteryLoseBiddingTime(int lotteryType, Date date)
 {
  scheduler = (Scheduler) this.ctt.getAttribute(TIMING_WORK_SCHEDULER);
  try
  {
   String lotteryName = "";
   switch (lotteryType)
   {
   case 1://
    lotteryName = "ssq";
    break;
   case 2://
   {
    lotteryName = "3D";
   }
    break;
   case 3://
   {
    lotteryName = "qlc";
   }
    break;
   case 4://
   {
    lotteryName = "23x5";
   }
    break;
   default:
    break;
   }

   loseBiddingJob = scheduler.getJobDetail("loseBiddingJob_" + lotteryName, "loseBiddingGroup");
   loseBiddingTrigger = (CronTrigger) scheduler.getTrigger("loseBiddingTrigger_" + lotteryName,
     "loseBiddingGroup");
   String time = loseBiddingTrigger.getCronExpression();
   if (!time.equals(this.timeFormat(date)))
   {
    loseBiddingTrigger = new CronTrigger("loseBiddingTrigger_" + lotteryName, "loseBiddingGroup",
      "loseBiddingJob_" + lotteryName, "loseBiddingGroup", this.timeFormat(date));
    Date ft = scheduler.rescheduleJob("loseBiddingTrigger_" + lotteryName, "loseBiddingGroup",
      loseBiddingTrigger);
    log.info(loseBiddingJob.getFullName() + " has been scheduled to run at: " + ft
      + " and excute based on expression: " + loseBiddingTrigger.getCronExpression());
   }
  } catch (Exception e)
  {
   log.error(e);
  }
 }

 


5.相关问题

配置完成后,定时任务不加载执行,在日志中报错:
java.lang.NoSuchMethodError: org.apache.commons.collections.SetUtils.orderedSet(Ljava/util/Set;)Ljava/util/Set;
这个是commons-collections.jar版本过低的原因,更换个新版本的就可以了!

还有,为了防止开发人员在本地测试时,执行定时任务造成数据冲突,需要对主机服务器Ip进行判断,只有指定的服务器上才可以执行定时任务!

Java代码
public boolean compareService(String thisIp)  
{  
    Properties properties = this.getProperties();  
    String serviceIp = "";  
    try 
    {  
        if (properties != null)  
        {  
            serviceIp = properties.getProperty("timing.work.serviceIp");  
            if (serviceIp != null && serviceIp.equals(thisIp))  
                return true;  
        }  
    } catch (Exception e)  
    {  
        log.error(e);  
    }  
    return false;  

public boolean compareService(String thisIp)
{
 Properties properties = this.getProperties();
 String serviceIp = "";
 try
 {
  if (properties != null)
  {
   serviceIp = properties.getProperty("timing.work.serviceIp");
   if (serviceIp != null && serviceIp.equals(thisIp))
    return true;
  }
 } catch (Exception e)
 {
  log.error(e);
 }
 return false;
}

 

 

quartz还可以对数据库操作,还有JobStore等等,以后应用到再说!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值