【Quartz】JavaWeb整合Quartz 实现动态调度并

本文详细介绍了使用Quartz任务调度系统实现定时任务的方法,包括数据库表建立、配置文件设置、监听器实现以及测试案例解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Written In The Font

需要:
1.导入WEB-INF/lib/quartz-2.2.1.jar
2.然后数据库建相关表格,可以去quartz-2.2.1\docs\dbTables目录下找到对应的数据库表格.(我这边Mysql , 导入 tables_mysql.sql 即可)
3.配置quartz.properties

#============================================================================
# Configure Main Scheduler Properties  
#============================================================================
org.quartz.scheduler.instanceName: wmuitpScheduler
org.quartz.scheduler.instanceId: AUTO
org.quartz.scheduler.skipUpdateCheck: true
#============================================================================
# Configure ThreadPool  
#============================================================================
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 10
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true  
#============================================================================
# Configure JobStore  
#============================================================================
org.quartz.jobStore.misfireThreshold: 60000
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties=false
org.quartz.jobStore.dataSource=myDS
org.quartz.jobStore.tablePrefix=qrtz_
org.quartz.jobStore.isClustered=true
#============================================================================
# Configure Datasources  
#============================================================================
org.quartz.dataSource.myDS.driver: com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL: jdbc:mysql://localhost:3307/itp
org.quartz.dataSource.myDS.user: root
org.quartz.dataSource.myDS.password: 123456
org.quartz.dataSource.myDS.maxConnections: 5
org.quartz.dataSource.myDS.validationQuery: select 0
基本步骤:
1.web.xml注册监听器ScheduleStartListener
2.监听器类sedion.jeffli.wmuitp.listener.ScheduleStartListener实现
3.测试案例第一步: Job 接口实现类JobTest
4.测试案例第二步:QuartzTest

web.xml注册监听器ScheduleStartListener

注册quartz监听器,监听项目是否启动或者重启.保证项目启动或重启时,所有任务会被重新安排到任务调度中.
web.xml添加一个Listener:

<!-- quartz监听器 -->  
<listener>
    <listener-class>sedion.jeffli.wmuitp.listener.ScheduleStartListener</listener-class>
</listener>

监听器类sedion.jeffli.wmuitp.listener.ScheduleStartListener实现

监听器类主要是实现recovery各个任务,重新恢复在triggerGroups组中所有的触发器,按新的trigger重新设置job执行.顺便说下,这个异常自定义(不需要删除即可): sedion.jeffli.wmuitp.exception.QuartzException;

package sedion.jeffli.wmuitp.listener;

import java.util.List;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;

import sedion.jeffli.wmuitp.exception.QuartzException;

public class ScheduleStartListener implements ServletContextListener
{

    public void contextDestroyed(ServletContextEvent sce) 
    {
        
    }

    public void contextInitialized(ServletContextEvent sce) 
    {
        try 
        {
            recovery();
        } 
        catch (Exception e)
        {
            throw new QuartzException(" ScheduleStartListener contextInitialized ERROR!!",e);
        }
    }
    

    public void recovery() 
    {
        
        Scheduler scheduler = null;
        
        try {
            
            SchedulerFactory schedulerFactory = new StdSchedulerFactory();
            scheduler = schedulerFactory.getScheduler();//可以通过SchedulerFactory创建一个Scheduler实例
            List<String> triggerGroups = scheduler.getTriggerGroupNames();//获取调度器中所有的触发器组
            System.out.println("调度器中所有的触发器组 size():"+triggerGroups.size());
            
            if(triggerGroups != null && triggerGroups.size() != 0)//重新恢复在triggerGroups组中所有的触发器
            {
                for (int i = 0; i < triggerGroups.size(); i++) 
                {
                        TriggerKey triggerKey = TriggerKey.triggerKey(triggerGroups.get(i), triggerGroups.get(i));
                        System.out.println("triggerKey:"+triggerKey);
                        
                        Trigger tg = scheduler.getTrigger(triggerKey);//获取trigger
                        System.out.println(triggerKey+" -> 执行时间 :"+tg.getNextFireTime());
                        
                        scheduler.rescheduleJob(triggerKey, tg);//按新的trigger重新设置job执行
                }
            }
            
            scheduler.start();
            
        } 
        catch (Exception e) 
        {
            throw new QuartzException("ScheduleStartListener  recovery() Error!", e);
        }
    }
}

测试案例第一步: Job 接口实现类JobTest

顾名思义,用于自定义任务,方法的实现.你可以在其中写入任意你想要在那个点上干的事情(操作数据库,前台显示等).在下面那处地方写入你想要写的: System.out.println( "添入需要加入任务的具体操作" ); .顺便说下,这个异常自定义(不需要删除即可):
package test.quartz;


import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;

import sedion.jeffli.wmuitp.exception.QuartzException;


public class JobTest implements Job{
    
    public JobTest() {}    
  
    public void execute(JobExecutionContext context)throws JobExecutionException
    {  
        
        JobDataMap data = context.getJobDetail().getJobDataMap();
        System.out.println("data.testId : "+data.getInt("testId")); //不需要可删除
        
        try
        {
            System.out.println("添入需要加入任务的具体操作");
        }
        catch (Exception e) 
        {
            throw new QuartzException("JobTest execute() ERROR !!", e);
        }
    }  
    
    public static void removeJob(JobKey jobKey, TriggerKey tiKey)throws SchedulerException
    { 
        
        SchedulerFactory sf     = new StdSchedulerFactory();
        Scheduler          sched     = sf.getScheduler();  
        
        sched.pauseTrigger(tiKey);            //停止触发器  
        sched.unscheduleJob(tiKey);            //移除触发器  
        sched.deleteJob(jobKey);            //删除任务  
        
    } 
}

测试案例第二步:QuartzTest

顾名思义,用于实现,检验.可以通过SchedulerFactory创建一个Scheduler实例,把触发器在集群节点实例命名的组只是为了区分(伐木)从什么地方定问调度重新执行此作业,如果它是正在进行时调度下去.

package test.quartz;

import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;

import java.util.Date;

import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.impl.StdSchedulerFactory;


public class QuartzTest
{

    public void run(String date, int id)throws Exception 
    {

        
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        Scheduler scheduler = schedulerFactory.getScheduler();//可以通过SchedulerFactory创建一个Scheduler实例
        
        //设置工作详情
        JobDetail job = newJob(JobTest.class) 
            .withIdentity("job_"+id, "test"+id)         // (String name, String group)把触发器在集群节点实例命名的组只是为了区分(伐木)从什么地方定问调度重新执行此作业,如果它是正在进行时调度下去...
            .requestRecovery()                             
            .build();
       
        job.getJobDataMap().put("testId", id);        //设置存储参数(不需要可删除)
        
       
        Date startDate = FormatDate.stringToDateAll(date);//Date转String
        //设置触发器
        SimpleTrigger trigger = (SimpleTrigger) newTrigger()
                .withIdentity("overdue"+id, "overdue"+id)//withIdentity("trigger", "group")
                .startAt(startDate)
                .build();
        
        scheduler.scheduleJob(job, trigger);
        scheduler.start();
        System.out.println("------- Start Scheduler ----------------");
    }
    
    public static void main(String[] args) throws Exception 
    {
        QuartzTest quartzOverdue = new QuartzTest();
        quartzOverdue.run("2014-07-02 00:30:00",666);//666,随便的吉祥数字
    }
}

这边,项目tomcat启动.这边我的主机时间是:
image

 然后我们运行:

public static void main(String[] args) throws Exception{
        QuartzTest quartzOverdue = new QuartzTest();
        quartzOverdue.run("2014-07-02 00:30:00",666);//666,随便的吉祥数字
    }

看控制台:

先输出

------- Start Scheduler ----------------

然后时间到了

添入需要加入任务的具体操作

然后测试 quartz的持久化.(持久化测试就是 先开启任务,然后 中间断开重启服务器),之间你会发现控制台:

今天我重写了下,:

public static void main(String[] args) throws Exception 
    {
        QuartzTest quartzOverdue = new QuartzTest();
        quartzOverdue.run("2014-07-02 10:00:00",6666);
    }
调度器中所有的触发器组 size():1
triggerKey:test6666.test6666
test6666.test6666 -> 执行时间 :Wed Jul 02 10:00:00 CST 2014






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值