quartz 动态添加任务、暂停、删除

web.xml,所有配置文件以application开头,项目启动就能一起加载了

 <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
			classpath*:/applicationContext*.xml
		</param-value>
  </context-param>


配置文件application-quartz.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"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">  
  	
    <bean name="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
        <property name="dataSource">  
            <ref bean="dataSource" />  
        </property>  
        <property name="applicationContextSchedulerContextKey" value="applicationContextKey" />  
        <property name="configLocation" value="classpath:quartz-cluster.properties" />
		<!-- 启动时延期2秒开始任务 -->
		<property name="startupDelay" value="2" />
    </bean>
</beans>  

quartz-cluster.properties

#demo settings
server.node_name=server1


#============================================================================
# Configure Datasources
#============================================================================
#quartz.jdbc.driver=com.mysql.jdbc.Driver
#quartz.jdbc.url=jdbc:mysql://192.168.1.99:3306/quartz?useUnicode=true&characterEncoding=utf-8
#quartz.jdbc.username=root
#quartz.jdbc.password=2cydb


#============================================================================
# Configure Main Scheduler Properties  
#============================================================================
org.quartz.scheduler.instanceName = ClusteredScheduler
org.quartz.scheduler.instanceId = AUTO
org.quartz.scheduler.skipUpdateCheck = true


#============================================================================
# Configure ThreadPool  
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 5
org.quartz.threadPool.threadPriority = 5


#============================================================================
# Configure JobStore  
#============================================================================
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.tablePrefix = QRTZ_


#Cluster setting
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 15000


#============================================================================
# Configure Plugins 
#============================================================================


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


#org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
#org.quartz.plugin.jobInitializer.fileNames = quartz_data.xml
#org.quartz.plugin.jobInitializer.failOnFileNotFound = true
#org.quartz.plugin.jobInitializer.scanInterval = 120
#org.quartz.plugin.jobInitializer.wrapInUserTransaction = false


还有quartz的表

#
# 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))
TYENGINEPE=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; 



@PersistJobDataAfterExecution
public class QuartzFactory extends QuartzJobBean{
	
	private static final Logger logger = LoggerFactory.getLogger(QuartzFactory.class);  
	

	@Override
	public void executeInternal(JobExecutionContext context) throws JobExecutionException {
		TaskLogService taskLogService = ApplicationContextHolder.getBean(TaskLogService.class);
		Task task = (Task)context.getMergedJobDataMap().get("task");
		
		TaskLog log = taskLogService.save(task.getId());
		
        logger.info("任务名称 = [" + task.getClassName() + "---------任务分组 "+task.getMethodName() + "]");
        taskLogService.finshLog(log.getId());
	} 
}


下面的两个类实际应用中都以放到util包里便捷管理
QuartzUtil 类

public class QuartzUtil {

	/**
	 * 转换为Task
	 * @param trigger
	 * @param job
	 * @return
	 */
	public static Task convert(Trigger trigger,Task job){
		
		job.setTaskName(trigger.getKey().getName());
		job.setTaskGroup(trigger.getKey().getGroup());
		job.setDescription("触发器:" + trigger.getKey()+"_"+trigger.getDescription());
		job.setEndTime(trigger.getEndTime());
		job.setStartTime(trigger.getStartTime());
		job.setNextFireTime(trigger.getNextFireTime());
		job.setPrevFireTime(trigger.getPreviousFireTime());
		job.setPriority(trigger.getPriority());
		Trigger.TriggerState triggerState = null;
		
		try {
			triggerState = getScheduler().getTriggerState(trigger.getKey());
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
		job.setStatus(triggerState.name());
		if (trigger instanceof CronTrigger) {
			CronTrigger cronTrigger = (CronTrigger) trigger;
			String cronExpression = cronTrigger.getCronExpression();
			job.setCronExpression(cronExpression);
		}
		return job;
	}
	
	/**
	 * 获取正在运行的计划任务
	 * @return
	 */
	public static Map<String,Trigger> getTriggers(){
		
		Map<String,Trigger> triggerMap = new HashMap<String,Trigger>();
		
		Scheduler scheduler = getScheduler();
		GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
		Set<JobKey> jobKeys = null;
		try {
			jobKeys = scheduler.getJobKeys(matcher);
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
		for (JobKey jobKey : jobKeys) {
			List<? extends Trigger> triggers = null;
			try {
				triggers = scheduler.getTriggersOfJob(jobKey);
			} catch (SchedulerException e1) {
				e1.printStackTrace();
			}
			for (Trigger trigger : triggers) {
				triggerMap.put(jobKey.getGroup()+"."+jobKey.getName(), trigger);
			}
		}
		return triggerMap;
	}
	
	/**
	 * 启动一个计划任务
	 * @return
	 * @throws SchedulerException 
	 */
	public static Date startTask(Task task) throws SchedulerException{
		String taskName = task.getTaskName();
		String taskGroup = task.getTaskGroup();

		Scheduler scheduler = getScheduler();
		TriggerKey triggerKey = TriggerKey.triggerKey(taskName, taskGroup);
		CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
		
		//不存在,创建一个
		if (null == trigger) {
			JobDetail jobDetail = JobBuilder.newJob(QuartzFactory.class).withIdentity(taskName, taskGroup).build();
			jobDetail.getJobDataMap().put("scheduleJob", task);
			//表达式调度构建器
			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(task.getCronExpression());
			//按新的cronExpression表达式构建一个新的trigger
			trigger = TriggerBuilder.newTrigger().withIdentity(taskName, taskGroup).withSchedule(scheduleBuilder).build();
			return scheduler.scheduleJob(jobDetail, trigger);
		} else {
			// Trigger已存在,那么更新相应的定时设置
			//表达式调度构建器
			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(task.getCronExpression());
			//按新的cronExpression表达式重新构建trigger
			trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
			//按新的trigger重新设置job执行
			return scheduler.rescheduleJob(triggerKey, trigger);
		}
	}
	/**
	 * 暂停任务执行
	 * @param taskName
	 * @param groupName
	 * @throws SchedulerException
	 */
	public static void pauseTask(String taskName,String groupName) throws SchedulerException{
		Scheduler scheduler = getScheduler();
		JobKey jobKey = JobKey.jobKey(taskName, groupName);
		
		scheduler.pauseTrigger(new TriggerKey(taskName, groupName));
//		scheduler.pauseJob(jobKey);
		
	}
	
	/**
	 * 重启计划任务
	 * @param taskName
	 * @param groupName
	 * @throws SchedulerException
	 */
	public static void resumeTask(String taskName,String groupName) throws SchedulerException{

		Scheduler scheduler = getScheduler();
		
		scheduler.resumeTrigger(new TriggerKey(taskName, groupName));
	}
	
	/**
	 * 删除计划任务
	 * @param taskName
	 * @param taskGroup
	 * @return
	 * @throws SchedulerException
	 */
	public static boolean deleteTask(String taskName, String taskGroup) throws SchedulerException {
		TriggerKey triggerKey = new TriggerKey(taskName, taskGroup);  
		
		Scheduler scheduler = getScheduler();
		scheduler.pauseTrigger(triggerKey);// 停止触发器
		return scheduler.unscheduleJob(triggerKey);// 移除触发器

	}

	public static Scheduler getScheduler(){
		 return ApplicationContextHolder.getBean(SchedulerFactoryBean.class).getScheduler();
	}


}

ApplicationContextHolder类

public class ApplicationContextHolder implements ApplicationContextAware {
	private static ApplicationContext applicationContext;

	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		ApplicationContextHolder.applicationContext = applicationContext;
	}

	public static ApplicationContext getApplicationContext() {
		return applicationContext;
	}

	@SuppressWarnings("unchecked")
	public static <T> T getBean(String name) {
		return (T) getApplicationContext().getBean(name);
	}
	
	public static <T> T getBean(Class<T> clazz) {
		return (T) getApplicationContext().getBean(clazz);
	}

	public static void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck) {
		getApplicationContext().getAutowireCapableBeanFactory().autowireBeanProperties(existingBean, autowireMode, dependencyCheck);
	}


参考了这两篇文章
http://www.meiriyouke.net/?p=140

http://my.oschina.net/u/1177710/blog/284608

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值