Quartz实战

https://my.oschina.net/yinxiaoling/blog/542336?fromerr=s3ko7u33

Quartz实战

>

一、内存型(1)


    <bean name="complexJobDetail"
        class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <property name="jobClass" value="com.java.job.XXXXXXXXX" />
        <property name="durability" value="true" />
    </bean>

    <bean id="cronTrigger"
        class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="complexJobDetail" />
        <!-- 每2分钟执行一次 -->
        <property name="cronExpression" value="0 0/2 * * * ?" />
    </bean>

    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="jobDetails">
            <list>
                <ref bean="complexJobDetail" />
            </list>
        </property>
        <propertyname="triggers">
            <list>
                <refbean="cronTrigger" />
            </list>
        </property>
    </bean>

其中XXXXXXXXX为你的任务类:继承 QuartzJobBean 重写executeInternal方法即可。

二、内存型(2)-防止并发执行

    <bean id="XXXXXXX" class="com.java.job.XXXXXXXXXXX" />
    <bean name="complexJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="XXXXXXX" />
        <property name="targetMethod" value="执行定时任务的方法名" />
                <!-- 防止并发执行 -->
        <property name="concurrent" value="false" />
    </bean>

    <bean id="cronTrigger"
        class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="complexJobDetail" />
        <!-- 每2分钟执行一次 -->
        <property name="cronExpression" value="0 0/2 * * * ?" />
    </bean>

    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <propertyname="jobDetails">
            <list>
                <refbean="complexJobDetail" />
            </list>
        </property>
        <propertyname="triggers">
            <list>
                <refbean="cronTrigger" />
            </list>
        </property>
    </bean>

此方法你实现的的类不需继承、实现任何类、接口。 另外多个job的话则做多个触发器和job然后加到list中间即可。

三、持久化

1、官网下载Quzrtz解压后在目录docs/datables中可以找到需要的建表语句。这里提供mysql-innodb的sql:
#
# In your Quartz properties file, you'll need to set 
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#
#
# By: Ron Cordell - roncordell
#  I didn't see this anywhere, so I thought I'd post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM.

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))
ENGINE=InnoDB;

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))
ENGINE=InnoDB;

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))
ENGINE=InnoDB;

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(120) 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))
ENGINE=InnoDB;

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))
ENGINE=InnoDB;

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),
INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;

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))
ENGINE=InnoDB;

CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;

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))
ENGINE=InnoDB;

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))
ENGINE=InnoDB;

CREATE TABLE QRTZ_LOCKS (
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR(40) NOT NULL,
PRIMARY KEY (SCHED_NAME,LOCK_NAME))
ENGINE=InnoDB;

CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);

CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);

CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);

commit;
2、Spring配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:task="http://www.springframework.org/schema/task" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd    
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/task
        http://www.springframework.org/schema/task/spring-task-3.2.xsd">

    <!-- quartz持久化存储 -->
    <bean name="quartzScheduler"
        class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="dataSource">
            <ref bean="dataSource" />
        </property>
        <property name="applicationContextSchedulerContextKey" value="applicationContext" />
        <property name="configLocation" value="classpath:quartz.properties" />
        <property name="quartzProperties">
            <props>
                <prop key="org.quartz.scheduler.instanceName">CRMscheduler</prop>
                <propkey="org.quartz.scheduler.instanceId">AUTO</prop>
                <!-- 线程池配置 -->
                <propkey="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
                <propkey="org.quartz.threadPool.threadCount">20</prop>
                <propkey="org.quartz.threadPool.threadPriority">5</prop>
                <propkey="org.quartz.jobStore.misfireThreshold">120000</prop>
                <!-- JobStore 配置 -->
                <propkey="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
                <!-- 集群配置 -->
                <propkey="org.quartz.jobStore.isClustered">true</prop>
                <propkey="org.quartz.jobStore.clusterCheckinInterval">15000</prop>
                <propkey="org.quartz.jobStore.maxMisfiresToHandleAtATime">1</prop>
                <!-- 数据表设置 -->
                <propkey="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
                <propkey="org.quartz.jobStore.dataSource">qzDS</prop>
            </props>
        </property>
        <!--应用启动完后 QuartzScheduler延时10秒再启动 -->
        <propertyname="startupDelay"value="10" />
        <!-- 注册触发器 -->
        <propertyname="triggers">
            <list>
                <refbean="cronTrigger" />
            </list>
        </property>
        <!-- 注册jobDetail -->
        <propertyname="jobDetails">
            <list>
                <refbean="complexJobDetail" />
            </list>
        </property>
    </bean>

    <beanname="complexJobDetail"class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <propertyname="jobClass"value="com.java.job.XXX" />
        <propertyname="durability"value="true" />
        <propertyname="group"value="jobGroupName_XXX" />
        <propertyname="name"value="jobName_XXX" />
    </bean>
    <beanid="cronTrigger"class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <propertyname="jobDetail"ref="complexJobDetail" />
        <!-- 每30分钟执行一次 -->
        <propertyname="cronExpression"value="0 0/30 * * * ?" />
        <propertyname="name"value="triggerName_XXX" />
        <propertyname="group"value="triggerGroupName_XXX" />
    </bean>
</beans>

看以看到我们这里自定义了触发器和job的名字、组名还有其他可以自定义的属性,大家可以自定义去试试。

另外一种配置文件形式的方法:

#Main Scheduler Settings
org.quartz.scheduler.instanceName=quartzScheduler
org.quartz.scheduler.instanceId=AUTO
org.quartz.scheduler.threadsInheritContextClassLoaderOfInitializer=true
org.quartz.scheduler.skipUpdateCheck=true
org.quartz.scheduler.batchTriggerAcquisitionMaxCount=100

#Configure JDBC-JobStoreTX
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties=true
org.quartz.jobStore.dataSource=myDS
org.quartz.jobStore.tablePrefix=QRTZ_
org.quartz.jobStore.isClustered=true
org.quartz.jobStore.acquireTriggersWithinLock=true
org.quartz.jobStore.clusterCheckinInterval = 600000

#Configure DataSources
org.quartz.dataSource.myDS.driver=com.alibaba.druid.proxy.DruidDriver
org.quartz.dataSource.myDS.URL=jdbc:mysql://127.0.0.1:3306/数据库名称?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
org.quartz.dataSource.myDS.user=用户名
org.quartz.dataSource.myDS.password=密码
org.quartz.dataSource.myDS.maxConnections=5
org.quartz.dataSource.myDS.validationQuery=select 1 from dual

org.quartz.scheduler.rmi.export=false
org.quartz.scheduler.rmi.proxy=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 Plugins
org.quartz.plugin.triggHistory.class = org.quartz.plugins.history.LoggingTriggerHistoryPlugin
org.quartz.plugin.triggHistory.triggerFiredMessage = Trigger {1}.{0} fired job {6}.{5} at: {4, date, HH:mm:ss MM/dd/yyyy}
org.quartz.plugin.triggHistory.triggerCompleteMessage =Trigger {1}.{0} completed firing job {6}.{5} at {4, date, HH:mm:ss MM/dd/yyyy}.

上面implements Job 实现execute方法 或者 继承 QuartzJobBean 重写executeInternal方法都可以,也可以换成防止并发的形式。

四、界面管理

Bean
import java.util.Date;

import org.quartz.JobDataMap;

public class JobEntity {

    private int jobId;

    private String jobType;

    private String jobGroup;

    private String jobName;

    private String triggerName;

    private String triggerGroupName;

    private String cronExpr;

    private Date previousFireTime;

    private Date nextFireTime;

    private String jobStatus;

    private long runTimes;

    private long duration;

    private Date startTime;

    private Date endTime;

    private String jobMemo;

    private String jobClass;

    private String jobMethod;

    private String jobObject;

    private int count;

    private JobDataMap jobDataMap;

    public int getJobId() {
        return jobId;
    }

    public void setJobId(int jobId) {
        this.jobId = jobId;
    }

    public String getJobType() {
        return jobType;
    }

    public void setJobType(String jobType) {
        this.jobType = jobType;
    }

    public String getJobGroup() {
        return jobGroup;
    }

    public void setJobGroup(String jobGroup) {
        this.jobGroup = jobGroup;
    }

    public String getJobName() {
        return jobName;
    }

    public void setJobName(String jobName) {
        this.jobName = jobName;
    }

    public String getTriggerName() {
        return triggerName;
    }

    public void setTriggerName(String triggerName) {
        this.triggerName = triggerName;
    }

    public String getTriggerGroupName() {
        return triggerGroupName;
    }

    public void setTriggerGroupName(String triggerGroupName) {
        this.triggerGroupName = triggerGroupName;
    }

    public String getCronExpr() {
        return cronExpr;
    }

    publicvoidsetCronExpr(String cronExpr) {
        this.cronExpr = cronExpr;
    }

    public Date getPreviousFireTime() {
        return previousFireTime;
    }

    publicvoidsetPreviousFireTime(Date previousFireTime) {
        this.previousFireTime = previousFireTime;
    }

    public Date getNextFireTime() {
        return nextFireTime;
    }

    publicvoidsetNextFireTime(Date nextFireTime) {
        this.nextFireTime = nextFireTime;
    }

    public String getJobStatus() {
        return jobStatus;
    }

    publicvoidsetJobStatus(String jobStatus) {
        this.jobStatus = jobStatus;
    }

    publiclonggetRunTimes() {
        return runTimes;
    }

    publicvoidsetRunTimes(long runTimes) {
        this.runTimes = runTimes;
    }

    publiclonggetDuration() {
        return duration;
    }

    publicvoidsetDuration(long duration) {
        this.duration = duration;
    }

    public Date getStartTime() {
        return startTime;
    }

    publicvoidsetStartTime(Date startTime) {
        this.startTime = startTime;
    }

    public Date getEndTime() {
        return endTime;
    }

    publicvoidsetEndTime(Date endTime) {
        this.endTime = endTime;
    }

    public String getJobMemo() {
        return jobMemo;
    }

    publicvoidsetJobMemo(String jobMemo) {
        this.jobMemo = jobMemo;
    }

    public String getJobClass() {
        return jobClass;
    }

    publicvoidsetJobClass(String jobClass) {
        this.jobClass = jobClass;
    }

    public String getJobMethod() {
        return jobMethod;
    }

    publicvoidsetJobMethod(String jobMethod) {
        this.jobMethod = jobMethod;
    }

    publicintgetCount() {
        return count;
    }

    publicvoidsetCount(int count) {
        this.count = count;
    }

    public String getJobObject() {
        return jobObject;
    }

    publicvoidsetJobObject(String jobObject) {
        this.jobObject = jobObject;
    }

    public JobDataMap getJobDataMap() {
        return jobDataMap;
    }

    publicvoidsetJobDataMap(JobDataMap jobDataMap) {
        this.jobDataMap = jobDataMap;
    }

}
公共类代码
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;

public class QuartzManager {

    private static SchedulerFactory ssf = new StdSchedulerFactory();

    private static final String JOB_NAME = "DEFAULT_JOB";

    private static final String JOB_GROUP_NAME = "DEFAULT_JOBGROUP";

    private static final String TRIGGER_NAME = "DEFAULT_TRIGGER";

    private static final String TRIGGER_GROUP_NAME = "DEFAULT_TRIGGERGROUP";

    /**
    * addJob(方法描述:添加定时任务) <br />
    * (方法适用条件描述: – 可选)
    * 
    * 使用默认的作业名称:    DEFAULT_JOB
    * 使用默认的作业组名称:    DEFAULT_JOBGROUP
    * 使用默认的触发器名称:    DEFAULT_TRIGGER
    * 使用默认的触发器组名称:DEFAULT_TRIGGERGROUP
    * 
    * @param cls        调用定时任务的class
    * @param cron        定时任务的时间通配符
    * void
    * @exception
    * @since  1.0.0
    */
    @SuppressWarnings("unchecked")
    public static void addJob(Class cls, String cron) {
        addJob(JOB_NAME, JOB_GROUP_NAME, TRIGGER_NAME, TRIGGER_GROUP_NAME, cls, cron);
    }
    /**
    * addJob(方法描述:添加定时任务) <br />
    * (方法适用条件描述: – 可选)
    * 
    * 使用默认的作业组名称:    DEFAULT_JOBGROUP
    * 使用默认的触发器组名称:DEFAULT_TRIGGERGROUP
    * 
    * @param jobName    作业名称
    * @param triggerName触发器名称
    * @param cls        调用定时任务的class
    * @param cron        定时任务的时间通配符
    * void
    * @exception
    * @since  1.0.0
    */
    @SuppressWarnings("unchecked")
    public static void addJob(String jobName, String triggerName, Class cls, String cron) {
        addJob(jobName, JOB_GROUP_NAME, triggerName, TRIGGER_GROUP_NAME, cls, cron);
    }
    /**
    * addJob(方法描述:添加一个定时任务) <br />
    * (方法适用条件描述: – 可选)
    * 
    * @param jobName            作业名称
    * @param jobGroupName        作业组名称
    * @param triggerName        触发器名称
    * @param triggerGroupName    触发器组名称
    * @param cls                定时任务的class
    * @param time                时间表达式
    * void
    * @exception
    * @since  1.0.0
    */
    @SuppressWarnings("unchecked")
    public static void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName, Class cls, String cron) {
        try {
            //获取调度器
            Scheduler sched = ssf.getScheduler();
            //创建一项作业
            JobDetail job = JobBuilder.newJob(cls).withIdentity(jobName, jobGroupName).build();
            //创建一个触发器
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroupName)
                    .withSchedule(CronScheduleBuilder.cronSchedule(cron)).build();
            //告诉调度器使用该触发器来安排作业
            sched.scheduleJob(job, trigger);
            // 启动
            if (!sched.isShutdown()) {
                sched.start();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    /**
    * modifyJobTime(方法描述:修改定时任务-先删除在新增) <br />
    * (方法适用条件描述: – 可选)
    * 
    * @param jobName            作业名称
    * @param jobGroupName        作业组名称
    * @param triggerName        触发器名称
    * @param triggerGroupName    触发器组名称
    * @param cron                时间表达式
    * void
    * @exception
    * @since  1.0.0
    */
    @SuppressWarnings("unchecked")
    public static voidmodifyJobTime(String jobName, String jobGroup, String triggerName, String triggerGroup, String cron) {
        try {
            Scheduler sched = ssf.getScheduler();
            CronTrigger trigger = (CronTrigger) sched.getTrigger(TriggerKey.triggerKey(triggerName, triggerGroup));
            if (trigger == null) {
                return;
            }
            String oldCron = trigger.getCronExpression();
            if (!oldCron.equalsIgnoreCase(cron)) {

                JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
                TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroup);

                JobDetail job = sched.getJobDetail(jobKey);
                Class jobClass = job.getJobClass();
                // 停止触发器
                sched.pauseTrigger(triggerKey);
                // 移除触发器
                sched.unscheduleJob(triggerKey);
                // 删除任务
                sched.deleteJob(jobKey);
                addJob(jobName, jobGroup, triggerName, triggerGroup, jobClass, cron);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    /**
    * modifyJobTime(方法描述:修改定时任务-只修改触发器和时间重启触发器) <br />
    * (方法适用条件描述: – 可选)
    * 
    * @param triggerName        触发器名称
    * @param triggerGroupName    触发器组名称
    * @param time
    * void
    * @exception
    * @since  1.0.0
    */
    publicstaticvoidmodifyJobTime(String triggerName, String triggerGroupName, String time) {
        try {
            Scheduler sched = ssf.getScheduler();
            CronTrigger trigger = (CronTrigger) sched.getTrigger(TriggerKey.triggerKey(triggerName, triggerGroupName));
            if (trigger == null) {
                return;
            }
            String oldTime = trigger.getCronExpression();
            if (!oldTime.equalsIgnoreCase(time)) {
                CronTrigger ct = (CronTrigger) trigger;
                // 修改时间
                ct.getTriggerBuilder().withSchedule(CronScheduleBuilder.cronSchedule(time)).build();
                // 重启触发器
                sched.resumeTrigger(TriggerKey.triggerKey(triggerName, triggerGroupName));
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    /**
    * removeJob(方法描述:删除默认组任务) <br />
    * (方法适用条件描述: – 可选)
    * 
    * @param jobName            作业名称
    * void
    * @exception
    * @since  1.0.0
    */
    publicstaticvoidremoveJob(String jobName) {
        try {
            Scheduler sched = ssf.getScheduler();
            // 停止触发器
            sched.pauseTrigger(TriggerKey.triggerKey(jobName, TRIGGER_GROUP_NAME));
            // 移除触发器
            sched.unscheduleJob(TriggerKey.triggerKey(jobName, TRIGGER_GROUP_NAME));
            // 删除任务
            sched.deleteJob(JobKey.jobKey(jobName, JOB_GROUP_NAME));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    /**
    * removeJob(方法描述:删除指定组任务) <br />
    * (方法适用条件描述: – 可选)
    * 
    * @param jobName            作业名称
    * @param jobGroupName        作业组名称
    * @param triggerName        触发器名称
    * @param triggerGroupName    触发器组名称
    * void
    * @exception
    * @since  1.0.0
    */
    publicstaticvoidremoveJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName) {
        try {
            Scheduler sched = ssf.getScheduler();
            // 停止触发器
            sched.pauseTrigger(TriggerKey.triggerKey(triggerName, triggerGroupName));
            // 移除触发器
            sched.unscheduleJob(TriggerKey.triggerKey(triggerName, triggerGroupName));
            // 删除任务
            sched.deleteJob(JobKey.jobKey(jobName, jobGroupName));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    /**
    * startJobs(方法描述:开始所有定时任务) <br />
    * (方法适用条件描述: – 可选)
    * void
    * @exception
    * @since  1.0.0
    */
    publicstaticvoidstartJobs() {
        try {
            Scheduler sched = ssf.getScheduler();
            sched.start();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
    * shutdownJobs(方法描述:停止所有定时任务) <br />
    * (方法适用条件描述: – 可选)
    * void
    * @exception
    * @since  1.0.0
    */
    publicstaticvoidshutdownJobs() {
        try {
            Scheduler sched = ssf.getScheduler();
            if (!sched.isShutdown()) {
                sched.shutdown();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
Ctroller代码
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.quartz.CronTrigger;
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.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

/** 
 * 类名称:JobController
 * @version
 */
@Controller
@RequestMapping(value = "/job")
public class JobController extends BaseController {

    @Resource(name = "quartzScheduler")
    private Scheduler quartzScheduler;

    @SuppressWarnings("unchecked")
    private List<JobEntity> getSchedulerJobInfo() throws SchedulerException {
        List<JobEntity> jobInfos = new ArrayList<JobEntity>();
        List<String> triggerGroupNames = quartzScheduler.getTriggerGroupNames();
        for (String triggerGroupName : triggerGroupNames) {
            Set<TriggerKey> triggerKeySet = quartzScheduler.getTriggerKeys(GroupMatcher.triggerGroupEquals(triggerGroupName));
            for (TriggerKey triggerKey : triggerKeySet) {
                Trigger t = quartzScheduler.getTrigger(triggerKey);
                if (t instanceof CronTrigger) {
                    CronTrigger trigger = (CronTrigger) t;
                    //CronTrigger trigger = (CronTrigger) quartzScheduler.getTrigger(triggerKey);
                    JobKey jobKey = trigger.getJobKey();
                    JobDetail jd = quartzScheduler.getJobDetail(jobKey);
                    //List<CronTrigger> triggers = (List<CronTrigger>) quartzScheduler.getTriggersOfJob(jobKey);
                    //CronTrigger cronTrigger = triggers.get(0);
                    JobEntity jobInfo = new JobEntity();
                    jobInfo.setJobName(jobKey.getName());
                    jobInfo.setJobGroup(jobKey.getGroup());
                    jobInfo.setTriggerName(triggerKey.getName());
                    jobInfo.setTriggerGroupName(triggerKey.getGroup());
                    jobInfo.setCronExpr(trigger.getCronExpression());
                    jobInfo.setNextFireTime(trigger.getNextFireTime());
                    jobInfo.setPreviousFireTime(trigger.getPreviousFireTime());
                    jobInfo.setStartTime(trigger.getStartTime());
                    jobInfo.setEndTime(trigger.getEndTime());
                    jobInfo.setJobClass(jd.getJobClass().getCanonicalName());
                    //jobInfo.setDuration(Long.parseLong(jd.getDescription()));
                    Trigger.TriggerState triggerState = quartzScheduler.getTriggerState(trigger.getKey());
                    jobInfo.setJobStatus(triggerState.toString());// NONE无, NORMAL正常, PAUSED暂停, COMPLETE完全, ERROR错误, BLOCKED阻塞 
                    JobDataMap map = quartzScheduler.getJobDetail(jobKey).getJobDataMap();
                    if (null != map && CollectionUtils.isNotEmpty(map.keySet())) {
                        jobInfo.setCount(Integer.parseInt((String) map.get("count")));
                        jobInfo.setJobDataMap(map);
                    } else {
                        jobInfo.setJobDataMap(new JobDataMap());
                    }
                    jobInfos.add(jobInfo);
                }
            }
        }
        return jobInfos;
    }
    //去列表定时任务页面
    @RequestMapping(value = "/goList")
    public ModelAndView goList() throws Exception {
        logBefore(logger, "去定时任务列表页面");
        ModelAndView mv = this.getModelAndView();
        PageData pd = new PageData();
        pd = this.getPageData();
        mv.setViewName("system/tools/task");
        mv.addObject("pd", pd);
        mv.addObject("jobInfos", getSchedulerJobInfo());
        logAfter(logger);
        return mv;
    }
    //去编辑定时任务页面
    @RequestMapping(value = "/goEdit")
    public ModelAndView goEdit() throws Exception {
        logBefore(logger, "去编辑定时任务页面");
        ModelAndView mv = this.getModelAndView();
        PageData pd = new PageData();
        pd = this.getPageData();
        String jobName = (String) pd.get("jobName");
        String jobGroupName = (String) pd.get("jobGroupName");
        JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
        JobDetail jd = quartzScheduler.getJobDetail(jobKey);
        List<CronTrigger> triggers = (List<CronTrigger>) quartzScheduler.getTriggersOfJob(jobKey);
        CronTrigger trigger = triggers.get(0);
        TriggerKey triggerKey = trigger.getKey();
        String cron = trigger.getCronExpression();
        pd.put("jobName", jobKey.getName());
        pd.put("jobGroup", jobKey.getGroup());
        pd.put("triggerName", triggerKey.getName());
        pd.put("triggerGroupName", triggerKey.getGroup());
        pd.put("cron", cron);
        pd.put("clazz", jd.getJobClass().getCanonicalName());
        mv.setViewName("system/tools/edit_job");
        mv.addObject("pd", pd);
        mv.addObject("msg", "edit");
        logAfter(logger);
        return mv;
    }
    //去新增定时任务页面
    @RequestMapping(value = "/goAdd")
    public ModelAndView goAdd() throws Exception {
        logBefore(logger, "去新增定时任务页面");
        ModelAndView mv = this.getModelAndView();
        PageData pd = new PageData();
        pd = this.getPageData();
        mv.setViewName("system/tools/edit_job");
        mv.addObject("pd", pd);
        mv.addObject("msg", "add");
        logAfter(logger);
        return mv;
    }
    //暂停任务
    @RequestMapping(value = "/pauseJob")
    @ResponseBody
    public ModelAndView pauseJob() throws Exception {
        logBefore(logger, "暂停任务");
        ModelAndView mv = this.getModelAndView();
        PageData pd = new PageData();
        pd = this.getPageData();
        String jobName = (String) pd.get("jobName");
        String jobGroupName = (String) pd.get("jobGroupName");
        JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
        quartzScheduler.pauseJob(jobKey);
        mv.addObject("data", "succ");
        mv.setViewName("system/tools/task");
        mv.addObject("pd", pd);
        mv.addObject("jobInfos", getSchedulerJobInfo());
        logAfter(logger);
        return mv;
    }
    //恢复任务
    @RequestMapping(value = "/resumeJob")
    public ModelAndView resumeJob() throws Exception {
        logBefore(logger, "恢复任务");
        ModelAndView mv = this.getModelAndView();
        PageData pd = new PageData();
        pd = this.getPageData();
        String jobName = (String) pd.get("jobName");
        String jobGroupName = (String) pd.get("jobGroupName");
        JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
        quartzScheduler.resumeJob(jobKey);
        mv.setViewName("system/tools/task");
        mv.addObject("pd", pd);
        mv.addObject("jobInfos", getSchedulerJobInfo());
        logAfter(logger);
        return mv;
    }
    //删除任务
    @RequestMapping(value = "/deleteJob")
    public ModelAndView deleteJob() throws Exception {
        logBefore(logger, "删除任务");
        ModelAndView mv = this.getModelAndView();
        PageData pd = new PageData();
        pd = this.getPageData();
        String jobName = (String) pd.get("jobName");
        String jobGroupName = (String) pd.get("jobGroupName");
        JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
        quartzScheduler.deleteJob(jobKey);
        mv.setViewName("system/tools/task");
        mv.addObject("pd", pd);
        mv.addObject("jobInfos", getSchedulerJobInfo());
        logAfter(logger);
        return mv;
    }
    //立即运行任务
    @RequestMapping(value = "/triggerJob")
    public ModelAndView triggerJob() throws Exception {
        logBefore(logger, "立即运行任务");
        ModelAndView mv = this.getModelAndView();
        PageData pd = new PageData();
        pd = this.getPageData();
        String jobName = (String) pd.get("jobName");
        String jobGroupName = (String) pd.get("jobGroupName");
        JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
        quartzScheduler.triggerJob(jobKey);
        mv.setViewName("system/tools/task");
        mv.addObject("pd", pd);
        logAfter(logger);
        return mv;
    }
    //添加一个定时任务
    @RequestMapping(value = "/add")
    public ModelAndView add() throws Exception {
        logBefore(logger, "添加定时任务");
        ModelAndView mv = this.getModelAndView();
        PageData pd = new PageData();
        pd = this.getPageData();
        String cron = (String) pd.get("cron");
        String clazz = (String) pd.get("clazz");
        String jobName = (String) pd.get("jobName");
        String jobGroupName = (String) pd.get("jobGroupName");
        String triggerName = (String) pd.get("triggerName");
        String triggerGroupName = (String) pd.get("triggerGroupName");
        QuartzManager.addJob(jobName, jobGroupName, triggerName, triggerGroupName, Class.forName(clazz), cron);
        mv.setViewName("system/tools/task");
        mv.addObject("pd", pd);
        mv.addObject("jobInfos", getSchedulerJobInfo());
        logAfter(logger);
        return mv;
    }
    //修改一个定时任务
    @RequestMapping(value = "/edit")
    public ModelAndView edit() throws Exception {
        logBefore(logger, "修改定时任务");
        ModelAndView mv = this.getModelAndView();
        PageData pd = new PageData();
        pd = this.getPageData();
        String cron = (String) pd.get("cron");
        String jobName = (String) pd.get("jobName");
        String jobGroupName = (String) pd.get("jobGroupName");
        String triggerName = (String) pd.get("triggerName");
        String triggerGroupName = (String) pd.get("triggerGroupName");
        QuartzManager.modifyJobTime(jobName, jobGroupName, triggerName, triggerGroupName, cron);
        mv.setViewName("system/tools/task");
        mv.addObject("pd", pd);
        mv.addObject("jobInfos", getSchedulerJobInfo());
        logAfter(logger);
        return mv;
    }
}

页面代码

 <table id="table_report" class="table table-striped table-bordered table-hover">
                    <thead>
                        <tr>
                            <!-- th class="center">序号</th-->
                            <th class="center">任务组名称</th>
                            <th class="center">定时任务名称</th>
                            <!-- <th class="center">触发器组名称</th>
                            <th class="center">触发器名称</th> -->
                            <th class="center">时间表达式</th>
                            <th class="center">上次运行时间</th>
                            <th class="center">下次运行时间</th>
                            <th class="center">任务状态</th>
                            <!-- <th class="center">已经运行时间</th> -->
                            <!-- <th class="center">持续运行时间</th> -->
                            <th class="center">开始时间</th>
                            <th class="center">结束时间</th>
                            <th class="center">任务类名</th>
                            <!-- <th class="center">方法名称</th> -->
                            <!-- <th class="center">jobObject</th> -->
                            <!-- <th class="center">运行次数</th> -->
                            <th class="center">操作</th>
                        </tr>
                    </thead>
                    <tbody>
                        <!-- 开始循环 -->
                        <c:choose>
                            <c:when test="${not empty jobInfos && jobInfos.size()>0}">
                                <c:forEach items="${jobInfos}" var="var" varStatus="vs">
                                    <tr>
                                        <td class='center' style=" auto;">${var.jobGroup}</td>
                                        <td class='center' style=" auto;">${var.jobName}</td>
                                        <%-- <td class='center' style=" auto;">${var.triggerGroupName}</td>
                                        <td class='center' style=" auto;">${var.triggerName}</td> --%>
                                        <td class='center' style=" auto;">${var.cronExpr}</td>
                                        <td class='center' style=" auto;"><fmt:formatDate value="${var.previousFireTime}" pattern="yyyy-MM-dd HH:mm:ss"/></td>
                                        <td class='center' style=" auto;"><fmt:formatDate value="${var.nextFireTime}" pattern="yyyy-MM-dd HH:mm:ss"/></td>
                                        <td class='center' style=" auto;">
                                            <c:if test="${var.jobStatus == 'NONE'}">
                                            <span class="label">未知</span>
                                            </c:if>
                                            <c:if test="${var.jobStatus == 'NORMAL'}">
                                            <span class="label label-success arrowed">正常运行</span>
                                            </c:if>
                                            <c:if test="${var.jobStatus == 'PAUSED'}">
                                            <span class="label label-warning">暂停状态</span>
                                            </c:if>
                                            <c:if test="${var.jobStatus == 'COMPLETE'}">
                                            <span class="label label-important arrowed-in">完成状态</span>
                                            </c:if>
                                            <c:if test="${var.jobStatus == 'ERROR'}">
                                            <span class="label label-info arrowed-in-right arrowed">错误状态</span>
                                            </c:if>
                                            <c:if test="${var.jobStatus == 'BLOCKED'}">
                                            <span class="label label-inverse">锁定状态</span>
                                            </c:if>
                                        </td>
                                        <%-- <td class='center' style=" auto;">${var.runTimes}</td> --%>
                                        <%-- <td class='center' style=" auto;">${var.duration}</td> --%>
                                        <td class='center' style=" auto;"><fmt:formatDate value="${var.startTime}" pattern="yyyy-MM-dd HH:mm:ss"/></td>
                                        <td class='center' style=" auto;"><fmt:formatDate value="${var.endTime}" pattern="yyyy-MM-dd HH:mm:ss"/></td>
                                        <td class='center' style=" auto;">${var.jobClass}</td>
                                        <%-- <td class='center' style=" auto;">${var.jobMethod}</td> --%>
                                        <%-- <td class='center' style=" auto;">${var.jobObject}</td> --%>
                                        <%-- <td class='center' style=" auto;">${var.count}</td> --%>
                                        <td class='center' style=" auto;">
                                            <a class="btn btn-minier btn-info" onclick="triggerJob('${var.jobName}','${var.jobGroup}');"><i class="icon-edit"></i>运行</a>
                                            <a class="btn btn-minier btn-purple" onclick="resumeJob('${var.jobName}','${var.jobGroup}');"><i class="icon-edit"></i>恢复</a>
                                            <a class="btn btn-minier btn-success" onclick="edit('${var.jobName}','${var.jobGroup}');"><i class="icon-edit"></i>编辑</a>
                                            <a class="btn btn-minier btn-warning" onclick="pauseJob('${var.jobName}','${var.jobGroup}');"><i class="icon-edit"></i>暂停</a>
                                            <a class="btn btn-minier btn-danger" onclick="deleteJob('${var.jobName}','${var.jobGroup}');"><i class="icon-edit"></i>删除</a>
                                        </td><!-- cron,jobName,jobGroupName,triggerName,triggerGroupName -->
                                    </tr>
                                </c:forEach>
                            </c:when>
                            <c:otherwise>
                                <tr class="main_info">
                                    <td colspan="100" class="center">没有相关数据</td>
                                </tr>
                            </c:otherwise>
                        </c:choose>
                    </tbody>
                </table>

  

原文地址:https://www.cnblogs.com/telwanggs/p/7238076.html