quartz集群配置+spring(一)

来源:互联网 发布:罗素 入门 知乎 编辑:程序博客网 时间:2024/05/16 19:07

最近在研究定时任务,想实现两个需求,一个是能够对定时任务操作,包括增删改,一个就是能够有集群功能,一个挂了,另一个可以立即启动.

quartz集群是通过持久化到数据库的,可以去官网下载sql。我的数据库是mysql
1.新建数据库
官网地址:http://www.quartz-scheduler.org/downloads/
我下载的2.2.3的,解压之后,quartz-2.2.3\docs\dbTables,有建表语句,
我用的是mysql,tables_mysql。顺便贴一下sql。

DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;DROP TABLE IF EXISTS QRTZ_LOCKS;DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;DROP TABLE IF EXISTS QRTZ_TRIGGERS;DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;DROP TABLE IF EXISTS QRTZ_CALENDARS;CREATE TABLE QRTZ_JOB_DETAILS  (    SCHED_NAME VARCHAR(120) NOT NULL,    JOB_NAME  VARCHAR(200) NOT NULL,    JOB_GROUP VARCHAR(200) NOT NULL,    DESCRIPTION VARCHAR(250) NULL,    JOB_CLASS_NAME   VARCHAR(250) NOT NULL,    IS_DURABLE VARCHAR(1) NOT NULL,    IS_NONCONCURRENT VARCHAR(1) NOT NULL,    IS_UPDATE_DATA VARCHAR(1) NOT NULL,    REQUESTS_RECOVERY VARCHAR(1) NOT NULL,    JOB_DATA BLOB NULL,    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP));CREATE TABLE QRTZ_TRIGGERS  (    SCHED_NAME VARCHAR(120) NOT NULL,    TRIGGER_NAME VARCHAR(200) NOT NULL,    TRIGGER_GROUP VARCHAR(200) NOT NULL,    JOB_NAME  VARCHAR(200) NOT NULL,    JOB_GROUP VARCHAR(200) NOT NULL,    DESCRIPTION VARCHAR(250) NULL,    NEXT_FIRE_TIME BIGINT(13) NULL,    PREV_FIRE_TIME BIGINT(13) NULL,    PRIORITY INTEGER NULL,    TRIGGER_STATE VARCHAR(16) NOT NULL,    TRIGGER_TYPE VARCHAR(8) NOT NULL,    START_TIME BIGINT(13) NOT NULL,    END_TIME BIGINT(13) NULL,    CALENDAR_NAME VARCHAR(200) NULL,    MISFIRE_INSTR SMALLINT(2) NULL,    JOB_DATA BLOB NULL,    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)        REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP));CREATE TABLE QRTZ_SIMPLE_TRIGGERS  (    SCHED_NAME VARCHAR(120) NOT NULL,    TRIGGER_NAME VARCHAR(200) NOT NULL,    TRIGGER_GROUP VARCHAR(200) NOT NULL,    REPEAT_COUNT BIGINT(7) NOT NULL,    REPEAT_INTERVAL BIGINT(12) NOT NULL,    TIMES_TRIGGERED BIGINT(10) NOT NULL,    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP));CREATE TABLE QRTZ_CRON_TRIGGERS  (    SCHED_NAME VARCHAR(120) NOT NULL,    TRIGGER_NAME VARCHAR(200) NOT NULL,    TRIGGER_GROUP VARCHAR(200) NOT NULL,    CRON_EXPRESSION VARCHAR(200) NOT NULL,    TIME_ZONE_ID VARCHAR(80),    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP));CREATE TABLE QRTZ_SIMPROP_TRIGGERS  (              SCHED_NAME VARCHAR(120) NOT NULL,    TRIGGER_NAME VARCHAR(200) NOT NULL,    TRIGGER_GROUP VARCHAR(200) NOT NULL,    STR_PROP_1 VARCHAR(512) NULL,    STR_PROP_2 VARCHAR(512) NULL,    STR_PROP_3 VARCHAR(512) NULL,    INT_PROP_1 INT NULL,    INT_PROP_2 INT NULL,    LONG_PROP_1 BIGINT NULL,    LONG_PROP_2 BIGINT NULL,    DEC_PROP_1 NUMERIC(13,4) NULL,    DEC_PROP_2 NUMERIC(13,4) NULL,    BOOL_PROP_1 VARCHAR(1) NULL,    BOOL_PROP_2 VARCHAR(1) NULL,    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)     REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP));CREATE TABLE QRTZ_BLOB_TRIGGERS  (    SCHED_NAME VARCHAR(120) NOT NULL,    TRIGGER_NAME VARCHAR(200) NOT NULL,    TRIGGER_GROUP VARCHAR(200) NOT NULL,    BLOB_DATA BLOB NULL,    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP));CREATE TABLE QRTZ_CALENDARS  (    SCHED_NAME VARCHAR(120) NOT NULL,    CALENDAR_NAME  VARCHAR(200) NOT NULL,    CALENDAR BLOB NOT NULL,    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME));CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS  (    SCHED_NAME VARCHAR(120) NOT NULL,    TRIGGER_GROUP  VARCHAR(200) NOT NULL,     PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP));CREATE TABLE QRTZ_FIRED_TRIGGERS  (    SCHED_NAME VARCHAR(120) NOT NULL,    ENTRY_ID VARCHAR(95) NOT NULL,    TRIGGER_NAME VARCHAR(200) NOT NULL,    TRIGGER_GROUP VARCHAR(200) NOT NULL,    INSTANCE_NAME VARCHAR(200) NOT NULL,    FIRED_TIME BIGINT(13) NOT NULL,    SCHED_TIME BIGINT(13) NOT NULL,    PRIORITY INTEGER NOT NULL,    STATE VARCHAR(16) NOT NULL,    JOB_NAME VARCHAR(200) NULL,    JOB_GROUP VARCHAR(200) NULL,    IS_NONCONCURRENT VARCHAR(1) NULL,    REQUESTS_RECOVERY VARCHAR(1) NULL,    PRIMARY KEY (SCHED_NAME,ENTRY_ID));CREATE TABLE QRTZ_SCHEDULER_STATE  (    SCHED_NAME VARCHAR(120) NOT NULL,    INSTANCE_NAME VARCHAR(200) NOT NULL,    LAST_CHECKIN_TIME BIGINT(13) NOT NULL,    CHECKIN_INTERVAL BIGINT(13) NOT NULL,    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME));CREATE TABLE QRTZ_LOCKS  (    SCHED_NAME VARCHAR(120) NOT NULL,    LOCK_NAME  VARCHAR(40) NOT NULL,     PRIMARY KEY (SCHED_NAME,LOCK_NAME));commit;

2.quartz配置文件
quartz-context.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"><context:annotation-config />  <beanclass="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="locations" value="classpath:jdbc.properties" /></bean>    <bean id="DataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">          <property name="driverClassName" value="com.mysql.jdbc.Driver" />          <property name="url" value="${jdbc.read.mysql.url}" />          <property name="username" value="${jdbc.read.mysql.username}" />          <property name="password" value="${jdbc.read.mysql.password}" />          <!-- 连接池最大使用连接数量 -->          <property name="maxActive" value="100" />          <!-- 初始化大小 -->          <property name="initialSize" value="10" />          <!-- 获取连接最大等待时间 -->          <property name="maxWait" value="60000" />          <!-- 连接池最小空闲 -->          <property name="minIdle" value="5" />          <!-- 逐出连接的检测时间间隔 -->          <property name="timeBetweenEvictionRunsMillis" value="3000" />          <!-- 最小逐出时间 -->          <property name="minEvictableIdleTimeMillis" value="300000" />          <!-- 测试有效用的SQL Query -->          <property name="validationQuery" value="SELECT 'x'" />          <!-- 连接空闲时测试是否有效 -->          <property name="testWhileIdle" value="true" />          <!-- 获取连接时测试是否有效 -->          <property name="testOnBorrow" value="false" />          <!-- 归还连接时是否测试有效 -->          <property name="testOnReturn" value="false" />      </bean>  <!-- 声明工厂 -->      <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">          <property name="dataSource" ref="DataSource" />          <property name="configLocation" value="classpath:quartz.properties" />          <!--applicationContextSchedulerContextKey:           是org.springframework.scheduling.quartz.SchedulerFactoryBean这个类中         把spring上下 文以key/value的方式存放在了quartz的上下文中了,          可以用applicationContextSchedulerContextKey所定义的key得到对应的spring上下文-->            <property name="applicationContextSchedulerContextKey" value="applicationContextKey"/>           </bean>  </beans>

3.1 jdbc数据库连接配置文件
jdbc.properties
#============================================================================# MySQL (READ)#============================================================================jdbc.read.mysql.driver=com.mysql.jdbc.Driverjdbc.read.mysql.url=jdbc:mysql://localhost:3306/film?useUnicode=true&characterEncoding=utf-8jdbc.read.mysql.username=rootjdbc.read.mysql.password=root#============================================================================# \u901a\u7528\u914d\u7f6e#============================================================================jdbc.initialSize=2jdbc.minIdle=2jdbc.maxIdle=20jdbc.maxActive=20jdbc.maxWait=60000jdbc.timeBetweenEvictionRunsMillis=60000jdbc.minEvictableIdleTimeMillis=300000jdbc.validationQuery=SELECT 1 FROM DUALjdbc.testWhileIdle=truejdbc.testOnBorrow=falsejdbc.testOnReturn=false

3.2 quartz配置文件 quartz.properties

#job存储方式org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX #超时时间org.quartz.jobStore.misfireThreshold = 60000 org.quartz.scheduler.instanceName = DefaultQuartzScheduler  org.quartz.scheduler.rmi.export = false  org.quartz.scheduler.rmi.proxy = false  org.quartz.scheduler.wrapJobExecutionInUserTransaction = false  org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool  #线程数量org.quartz.threadPool.threadCount = 10  #优先线程数量org.quartz.threadPool.threadPriority = 5  org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true#==============================================================  #Configure Main Scheduler Properties  #==============================================================   org.quartz.scheduler.instanceName = quartzSchedulerorg.quartz.scheduler.instanceId = AUTO#==============================================================  #Configure JobStore  #orgorg.quartz.jobStore.class = org.quartz.simpl.RAMJobStore  orgorg.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTXorgorg.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.HSQLDBDelegateorgorg.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegateorg.quartz.jobStore.useProperties = falseorg.quartz.jobStore.tablePrefix = QRTZ_#quartz cluster mode(如果要开启集群模式,将下面的改为true)org.quartz.jobStore.isClustered = falseorg.quartz.jobStore.clusterCheckinInterval = 10000org.quartz.jobStore.maxMisfiresToHandleAtATime=1

4.新建job的pojo ,用于数据库的增删改成ScheduleJob:

package com.test.job.schedule.pojo;import java.io.Serializable;import java.util.Date;import com.test.job.util.DateUtil;public class ScheduleJob implements Serializable{    private static final long serialVersionUID = 1L;    private String jobId;    private String jobName;    private String jobGroup;    private String jobStatus;    private String cronExpression;    private Date startTime;    private String desc;    private Object data;    public String scheduleClass;//作用的方法    public Date previousTime;//上次执行时间    public Date nextTime;//下次执行时间    //set get .....public String getJobId() {return jobId;}public void setJobId(String jobId) {this.jobId = jobId;}public String getJobName() {return jobName;}public void setJobName(String jobName) {this.jobName = jobName;}public String getJobGroup() {return jobGroup;}public void setJobGroup(String jobGroup) {this.jobGroup = jobGroup;}public String getJobStatus() {return jobStatus;}public void setJobStatus(String jobStatus) {this.jobStatus = jobStatus;}public String getCronExpression() {return cronExpression;}public void setCronExpression(String cronExpression) {this.cronExpression = cronExpression;}public Date getStartTime() {return startTime;}public void setStartTime(Date startTime) {this.startTime = startTime;}public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}public String getScheduleClass() {return scheduleClass;}public void setScheduleClass(String scheduleClass) {this.scheduleClass = scheduleClass;}public Date getPreviousTime() {return previousTime;}public void setPreviousTime(Date previousTime) {this.previousTime = previousTime;}public Date getNextTime() {return nextTime;}public void setNextTime(Date nextTime) {this.nextTime = nextTime;}@Overridepublic String toString() {return "ScheduleJob [jobId=" + jobId + ", jobName=" + jobName + ", jobGroup=" + jobGroup + ", jobStatus="+ jobStatus + ", cronExpression=" + cronExpression + ", startTime=" + startTime + ", desc=" + desc+ ", data=" + data + ", scheduleClass=" + scheduleClass + ", previousTime=" + previousTime+ ", nextTime=" + nextTime + "]";}}

5.新建操作quartz数据库的Service类 JobService:

添加的时候,如果想添加简单的触发器,就改成simpleTrigger(比如5分钟后执行之类的),我这里用的是cron表达式,所以是cronTrigger。

不同的触发器存的表也一样,表不多,一看就明白。

package com.test.job.test.servicce;import java.util.ArrayList;import java.util.List;import org.quartz.CronScheduleBuilder;import org.quartz.CronTrigger;import org.quartz.Job;import org.quartz.JobBuilder;import org.quartz.JobDataMap;import org.quartz.JobDetail;import org.quartz.JobKey;import org.quartz.Scheduler;import org.quartz.SchedulerException;import org.quartz.Trigger;import org.quartz.TriggerBuilder;import org.quartz.TriggerKey;import org.quartz.impl.matchers.GroupMatcher;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.test.job.schedule.pojo.ScheduleJob;public class JobService {    static ApplicationContext context = new ClassPathXmlApplicationContext(            "quartz-context.xml");    static Scheduler scheduler = (Scheduler) context.getBean("scheduler");//@Autowired//static Scheduler scheduler;    /**     * 添加或修改任务     * @param job     * @param jobClass     * @throws SchedulerException     */    public static void addOrUpdateJob(ScheduleJob job, Class<? extends Job> jobClass)            throws SchedulerException {        TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(),job.getJobGroup());        // 获取trigger        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);//        SimpleTriggerImpl  trigger =  (SimpleTriggerImpl) scheduler.getTrigger(triggerKey);        // 不存在,创建一个        if (null == trigger) {            System.out.println("new");            JobDetail jobDetail = JobBuilder.newJob(jobClass)                    .withIdentity(job.getJobName(), job.getJobGroup()).build();            jobDetail.getJobDataMap().put("data", job.getData());            System.out.println("jobDetail"+jobDetail);            // 表达式调度构建器          CronScheduleBuilder scheduleBuilder = CronScheduleBuilder                  .cronSchedule(job.getCronExpression());//             按新的cronExpression表达式构建一个新的trigger          trigger = TriggerBuilder.newTrigger()                  .withIdentity(job.getJobName(), job.getJobGroup())                  .withSchedule(scheduleBuilder).build();//            ScheduleBuilder<?> schedBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(R.TIME_INTERVAL).withRepeatCount(-1);//            trigger = (SimpleTriggerImpl) TriggerBuilder.newTrigger()//            .withIdentity(job.getJobName(), job.getJobGroup()).startAt(job.getStartTime()).withSchedule(schedBuilder).build();            scheduler.scheduleJob(jobDetail, trigger);        } else {            System.out.println("reset");            // Trigger已存在,那么更新相应的定时设置            // 表达式调度构建器          CronScheduleBuilder scheduleBuilder = CronScheduleBuilder                  .cronSchedule(job.getCronExpression());//             按新的cronExpression表达式重新构建trigger          trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)                  .withSchedule(scheduleBuilder).build();//            ScheduleBuilder<?> schedBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(R.TIME_INTERVAL).withRepeatCount(-1);//            trigger = (SimpleTriggerImpl) TriggerBuilder.newTrigger()//                    .withIdentity(job.getJobName(), job.getJobGroup()).startAt(job.getStartTime()).withSchedule(schedBuilder).build();            // 按新的trigger重新设置job执行            JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup());            scheduler.getJobDetail(jobKey).getJobDataMap().put("data", job.getData());            System.out.println("scheduler.rescheduleJob");            scheduler.rescheduleJob(triggerKey, trigger);        }    }    /**     * 暂停任务     * @param job     * @throws SchedulerException     */    public static void pauseJob(ScheduleJob job) throws SchedulerException {        JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup());        scheduler.pauseJob(jobKey);    }    /**     * 恢复单个任务      * @param job     * @throws SchedulerException     */    public static void recoveryJob(ScheduleJob job) throws SchedulerException {        JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup());        scheduler.resumeJob(jobKey);    }    /**     * 全部恢复     * @param job     * @throws SchedulerException     */    public static void resumeAll() throws SchedulerException{        scheduler.resumeAll();    }    /**     * 查询任务信息     * @throws SchedulerException     */    public static void queryJob() throws SchedulerException {        for (String groupName : scheduler.getJobGroupNames()) {            for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) {                String jobName = jobKey.getName();                String jobGroup = jobKey.getGroup();                System.out.println("jobKey:"+jobKey);                JobDetail jobDetail = scheduler.getJobDetail(jobKey);                Class<? extends Job> jobClass = jobDetail.getJobClass();                List<Trigger> triggers = (List<Trigger>) scheduler.getTriggersOfJob(jobKey);                Trigger trigger = triggers.get(0);                System.out.println("[jobName] : " + jobName                         + " [groupName] : "+ jobGroup                         + " [nextFireTime]: " + trigger.getNextFireTime()                        + " [jobClass]: " + jobClass                        );            }        }    }    /**     * 获取任务列表     * @return     * @throws SchedulerException      * @exception      * JobDetail     */    public static List<ScheduleJob> getJobList() throws SchedulerException {    List<ScheduleJob> list = new ArrayList<ScheduleJob>();    for (String groupName : scheduler.getJobGroupNames()) {            for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) {            ScheduleJob sJob = new ScheduleJob();                String jobName = jobKey.getName();                String jobGroup = jobKey.getGroup();                System.out.println("jobKey:"+jobKey);                JobDetail jobDetail = scheduler.getJobDetail(jobKey);                Class<? extends Job> jobClass = jobDetail.getJobClass();                List<Trigger> triggers = (List<Trigger>) scheduler.getTriggersOfJob(jobKey);                TriggerKey triggerKey = TriggerKey.triggerKey(jobName,jobGroup);                // 获取trigger                CronTrigger cronTri = (CronTrigger) scheduler.getTrigger(triggerKey);                String cronExpression = cronTri.getCronExpression();                sJob.setCronExpression(cronExpression);                sJob.setJobGroup(jobGroup);                sJob.setJobName(jobName);                sJob.setDesc(jobDetail.getDescription());                sJob.setData(jobDetail.getJobDataMap());                sJob.setStartTime(triggers.get(0).getStartTime());                sJob.setPreviousTime(triggers.get(0).getPreviousFireTime());                sJob.setNextTime(triggers.get(0).getNextFireTime());                sJob.setScheduleClass(jobClass.toString());                Trigger trigger = triggers.get(0);                list.add(sJob);                System.out.println("[jobName] : " + jobName                         + " [groupName] : "+ jobGroup                         + " [nextFireTime]: " + trigger.getNextFireTime()                        + " [jobClass]: " + jobClass                        );            }        }    return list;    }    /**     * 删除任务     * @param job     * @throws SchedulerException     */    public static void delelteJob(ScheduleJob job) throws SchedulerException {        JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup());        scheduler.deleteJob(jobKey);    }        /**     * 同时删除任务和定时器     * @param job     * @throws SchedulerException     */    public static void delelteJobAndTrigger(ScheduleJob job) throws SchedulerException {         JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup());         TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(),job.getJobGroup());         scheduler.pauseTrigger(triggerKey);         scheduler.unscheduleJob(triggerKey);         scheduler.deleteJob(jobKey);    }    /**     * 立即执行     * @param job     * @throws SchedulerException     */    public static void triggerNow(ScheduleJob job) throws SchedulerException{        JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup());        scheduler.triggerJob(jobKey);    }    /**     * 立即执行     * @param job     * @throws SchedulerException     */    public static void triggerNow(ScheduleJob job,JobDataMap data) throws SchedulerException{        JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup());        scheduler.triggerJob(jobKey,data);    }}

6.新建两个运行的任务类,需要实现job接口:

HelloWorld:

package com.test.job.test.job;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;public class HelloWorld implements Job{@Overridepublic void execute(JobExecutionContext context)throws JobExecutionException {System.out.println("Hello World....every 30 seconds");}}

MyJob:

package com.test.job.test.job;import java.util.Date;import org.quartz.DisallowConcurrentExecution;import org.quartz.Job;import org.quartz.JobDataMap;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;//这里注解的意思是 任务是否可以并发 加上注解表示不可以并发@DisallowConcurrentExecutionpublic class MyJob implements Job{    @Override    public void execute(JobExecutionContext context)            throws JobExecutionException {        //在任务里 可以通过getJobDataMap()传自己需要用的一些数据//        JobDataMap jdm = context.getJobDetail().getJobDataMap();        //TODO//        System.out.println(jdm.get("data"));        System.out.println("Myjob..." + (new Date().getTime())/365/24/3600);    }}

7.新建一个test类,将任务持久化到数据库:

package com.test.job.test;import java.util.Date;import java.util.List;import org.quartz.SchedulerException;import com.test.job.schedule.pojo.ScheduleJob;import com.test.job.test.job.HelloWorld;import com.test.job.test.job.MyJob;import com.test.job.test.servicce.JobService;public class Test {    public static void getJobDataFromQueue(){        ScheduleJob job = new ScheduleJob();        job.setJobId("10001" );        job.setJobName("test1");        job.setJobGroup("test-group");        //时间可以自己设置        job.setStartTime(new Date());        job.setCronExpression("*/10 * * * * ?");        job.setData("这里是传入job的数据");        ScheduleJob job2 = new ScheduleJob();        job2.setJobId("10002" );        job2.setJobName("test2");        job2.setJobGroup("test-group2");        //时间可以自己设置        job2.setStartTime(new Date());        job2.setCronExpression("*/20 * * * * ?");        job2.setData("这里是传入HelloWorld的数据");        try {//            JobService.addOrUpdateJob(job, MyJob.class);//            JobService.addOrUpdateJob(job2, HelloWorld.class);            List<ScheduleJob> list = JobService.getJobList();            for (ScheduleJob scheduleJob : list) {System.out.println(scheduleJob);}        } catch (SchedulerException e) {            e.printStackTrace();        }    }    public static void main(String[] args) {        getJobDataFromQueue();    }}

如果有任务想持久化,就在test执行addOrUpdateJob方法。
然后在正常的项目启动的时候,引入quartz-context.xml的配置文件,容器启动后就会开始执行任务。

比如我这里的是,root-context.xml:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"><context:annotation-config /><context:component-scan base-package="com.test.job" /><!-- Root Context: defines shared resources visible to all other web components --><!-- 数据库配置--><import resource="classpath:database-context.xml"/><!-- quartz 定时任务--><import resource="classpath:quartz-context.xml"/></beans>

这里说一下集群的情况:
配置集群模式,org.quartz.jobStore.isClustered = ture
同时启动两台tomcat,只有一台在执行内容。停掉这台,另一台会继续执行。