Spring+Quartz 从数据库中获取定时任务和定时时间,动态实现对定时任务的增删改查

由于公司的新接得项目要实现一批数据的同步,通过外围厂商提供的一系列各个系统的webervices接口定时将数据同步到我们开发的共享平台上,由于厂商系统的数据是不断在变化以及各系统闲忙时的特点,所以定时同步任务的执行必须在时间上能够动态配置。因此,我们需要动态的从数据库中获取配置信息,以改变各个定时间的执行规则,废话不说了,上代码:(我利用的是ssh框架直接写的,框架搭建不再叙述)

1.创建数据表(我用的是mysql)

DROP TABLE IF EXISTS `t_wsdoc`;
CREATE TABLE `t_wsdoc` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `triggername` varchar(50) NOT NULL,
  `jobdetailname` varchar(50) NOT NULL,
  `cronexpression` varchar(50) NOT NULL,
  `targetobject` varchar(50) NOT NULL,
  `methodname` varchar(50) NOT NULL,
  `concurrent` char(10) NOT NULL DEFAULT '0',
  `state` char(10) NOT NULL DEFAULT '1',
  `isspringbean` char(10) NOT NULL DEFAULT '0',
  `readme` varchar(100) DEFAULT NULL,
  `reserved1` varchar(50) DEFAULT NULL,
  `reserved2` varchar(50) DEFAULT NULL,
  `reserved3` varchar(50) DEFAULT NULL,
  `reserved4` varchar(50) DEFAULT NULL,
  `reserved5` varchar(50) DEFAULT NULL,
  `reserved6` varchar(50) DEFAULT NULL,
  `reserved7` varchar(50) DEFAULT NULL,
  `reserved8` varchar(50) DEFAULT NULL,
  `reserved9` varchar(50) DEFAULT NULL,
  `reserved10` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `t_wsdoc` VALUES ('1', 'triggername', 'detailname', '0/5 * * * * ?', 'com.framework.timer.ISCSynAllData', 'run', '\'0\'', '\'1\'', '\'0\'', '说明', null, null, null, null, null, null, null, null, null, null);

2.创建表对应的实体类

package ...自定义;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

import com.framework.model.AbstractEntity;


@Entity
@Table(name = "WSDOC", schema = "")
public class Wsdoc extends AbstractEntity{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Long id;
	// 设置trigger名称
	private String triggername;  
	//设置表达式
	private String cronexpression;
	// 设置Job名称
	private String jobdetailname;
	//任务类名
	private String targetobject;
	//类名对应的方法名
	private String methodname;
	//设置是否并发启动任务 0是false 非0是true
	private String concurrent;
	// 如果计划任务不存则为1 存在则为0
	private String state;
	private String readme;
	//是否是已经存在的springBean 1是  0 否
	private String isspringbean;
	/** 预留字段1 */
	private String reserved1;
	/** 预留字段2 */
	private String reserved2;
	/** 预留字段3 */
	private String reserved3;
	/** 预留字段4 */
	private String reserved4;
	/** 预留字段5 */
	private String reserved5;
	/** 预留字段6 */
	private String reserved6;
	/** 预留字段7 */
	private String reserved7;
	/** 预留字段8 */
	private String reserved8;
	/** 预留字段9 */
	private String reserved9;
	/** 预留字段10 */
	private String reserved10;
	// Constructors

	/** default constructor */
	public Wsdoc() {
	}

	/** full constructor */
	public Wsdoc(String triggername, String cronexpression,
			String jobdetailname, String targetobject, String methodname,
			String concurrent, String state, String readme,String isspringbean) {
		this.triggername = triggername;
		this.cronexpression = cronexpression;
		this.jobdetailname = jobdetailname;
		this.targetobject = targetobject;
		this.methodname = methodname;
		this.concurrent = concurrent;
		this.state = state;
		this.readme = readme;
		this.isspringbean=isspringbean;
	}
	@Id
	@Column(name = "ID", unique = true, nullable = false, precision = 10, scale = 0)
	//@GeneratedValue(strategy = GenerationType.SEQUENCE,generator="WSDOC_ID") //如果为oracle则可以创建一个序列,便于插入数据用
	//@SequenceGenerator(initialValue=0,name="WSDOC_ID",sequenceName="WSDOC_ID",allocationSize=1)
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}
    
	@Column(name = "TRIGGERNAME",nullable = false,length=100)
	public String getTriggername() {
		return this.triggername;
	}

	public void setTriggername(String triggername) {
		this.triggername = triggername;
	}
	
	@Column(name = "CRONEXPRESSION",nullable = false,length=100)
	public String getCronexpression() {
		return this.cronexpression;
	}

	public void setCronexpression(String cronexpression) {
		this.cronexpression = cronexpression;
	}
	
	@Column(name = "JOBDETAILNAME",nullable = false,length=100)
	public String getJobdetailname() {
		return this.jobdetailname;
	}

	public void setJobdetailname(String jobdetailname) {
		this.jobdetailname = jobdetailname;
	}
	@Column(name = "TARGETOBJECT",nullable = false,length=100)
	public String getTargetobject() {
		return this.targetobject;
	}

	public void setTargetobject(String targetobject) {
		this.targetobject = targetobject;
	}
	@Column(name = "METHODNAME",nullable = false,length=100)
	public String getMethodname() {
		return this.methodname;
	}

	public void setMethodname(String methodname) {
		this.methodname = methodname;
	}
	@Column(name = "CONCURRENT",nullable = false,length=100)
	public String getConcurrent() {
		return this.concurrent;
	}

	public void setConcurrent(String concurrent) {
		this.concurrent = concurrent;
	}
	@Column(name = "STATE",nullable = false,length=100)
	public String getState() {
		return this.state;
	}

	public void setState(String state) {
		this.state = state;
	}
	@Column(name = "README",nullable = false,length=100)
	public String getReadme() {
		return this.readme;
	}

	public void setReadme(String readme) {
		this.readme = readme;
	}
	@Column(name = "ISSPRINGBEAN",nullable = false,length=100)
	public String getIsspringbean() {
		return isspringbean;
	}

	public void setIsspringbean(String isspringbean) {
		this.isspringbean = isspringbean;
	}
	@Column(name = "RESERVED_1",length=100)
	public String getReserved1() {
		return reserved1;
	}

	public void setReserved1(String reserved1) {
		this.reserved1 = reserved1;
	}
	@Column(name = "RESERVED_2",length=100)
	public String getReserved2() {
		return reserved2;
	}

	public void setReserved2(String reserved2) {
		this.reserved2 = reserved2;
	}
	@Column(name = "RESERVED_3",length=100)
	public String getReserved3() {
		return reserved3;
	}

	public void setReserved3(String reserved3) {
		this.reserved3 = reserved3;
	}
	@Column(name = "RESERVED_4",length=100)
	public String getReserved4() {
		return reserved4;
	}

	public void setReserved4(String reserved4) {
		this.reserved4 = reserved4;
	}
	@Column(name = "RESERVED_5",length=100)
	public String getReserved5() {
		return reserved5;
	}

	public void setReserved5(String reserved5) {
		this.reserved5 = reserved5;
	}
	@Column(name = "RESERVED_6",length=100)
	public String getReserved6() {
		return reserved6;
	}

	public void setReserved6(String reserved6) {
		this.reserved6 = reserved6;
	}
	@Column(name = "RESERVED_7",length=100)
	public String getReserved7() {
		return reserved7;
	}

	public void setReserved7(String reserved7) {
		this.reserved7 = reserved7;
	}
	@Column(name = "RESERVED_8",length=100)
	public String getReserved8() {
		return reserved8;
	}

	public void setReserved8(String reserved8) {
		this.reserved8 = reserved8;
	}
	@Column(name = "RESERVED_9",length=100)
	public String getReserved9() {
		return reserved9;
	}

	public void setReserved9(String reserved9) {
		this.reserved9 = reserved9;
	}
	@Column(name = "RESERVED_10",length=100)
	public String getReserved10() {
		return reserved10;
	}

	public void setReserved10(String reserved10) {
		this.reserved10 = reserved10;
	}



}
3.核心Java代码 

package com.framework.timer;

import java.text.ParseException;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.CronTriggerBean;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;

import cn.edu.svtcc.datas.model.Wsdoc;
import cn.edu.svtcc.datas.service.WsdocService;



public class QuartzManager implements BeanFactoryAware {
	private Logger log = Logger.getLogger(QuartzManager.class);
	private Scheduler scheduler;
	private static BeanFactory beanFactory = null;
   
	@Autowired
    private WsdocService wsdocService;

	@SuppressWarnings("unused")
	private void reScheduleJob() throws Exception, ParseException {
		// 通过查询数据库里计划任务来配置计划任务
		
		List<Wsdoc> quartzList = wsdocService.getAllTarger(); //从数据库中获取所有的配置信息,根据自己的获取方式来写,此不赘述
                Wsdoc tbcq=new Wsdoc();
		tbcq.setTriggername("triggername");
		tbcq.setCronexpression("0/5 * * * * ?");
		tbcq.setJobdetailname("detailname");
		tbcq.setTargetobject("com.framework.timer.ISCSynAllData");
		tbcq.setMethodname("run");
		tbcq.setConcurrent("1");
		tbcq.setState("1");
		tbcq.setReadme("readme");
		tbcq.setIsspringbean("0");
		quartzList.add(tbcq);*/
		//this.getConfigQuartz();
		if (quartzList != null && quartzList.size() > 0) {
			for (Wsdoc tbcq1 : quartzList) {
				configQuatrz(tbcq1);
			}
		}
	}

	public boolean configQuatrz(Wsdoc tbcq) {
		boolean result = false;
		try {
			// 运行时可通过动态注入的scheduler得到trigger
			CronTriggerBean trigger = (CronTriggerBean) scheduler.getTrigger(
					tbcq.getTriggername(), Scheduler.DEFAULT_GROUP);
			// 如果计划任务已存在则调用修改方法
			if (trigger != null) {
				change(tbcq, trigger);
			} else {
				// 如果计划任务不存在并且数据库里的任务状态为可用时,则创建计划任务
				if (tbcq.getState().equals("1")) {
					this.createCronTriggerBean(tbcq);
				}
			}
			result = true;
		} catch (Exception e) {
			result = false;
			e.printStackTrace();
		}

		return result;
	}

	public void change(Wsdoc tbcq, CronTriggerBean trigger)
			throws Exception {
		// 如果任务为可用
		if (tbcq.getState().equals("1")) {
			// 判断从DB中取得的任务时间和现在的quartz线程中的任务时间是否相等
			// 如果相等,则表示用户并没有重新设定数据库中的任务时间,这种情况不需要重新rescheduleJob
			if (!trigger.getCronExpression().equalsIgnoreCase(
					tbcq.getCronexpression())) {
				trigger.setCronExpression(tbcq.getCronexpression());
				scheduler.rescheduleJob(tbcq.getTriggername(),
						Scheduler.DEFAULT_GROUP, trigger);
				log.info(new Date() + ": 更新" + tbcq.getTriggername() + "计划任务");
			}
		} else {
			// 不可用
			scheduler.pauseTrigger(trigger.getName(), trigger.getGroup());// 停止触发器
			scheduler.unscheduleJob(trigger.getName(), trigger.getGroup());// 移除触发器
			scheduler.deleteJob(trigger.getJobName(), trigger.getJobGroup());// 删除任务
			log.info(new Date() + ": 删除" + tbcq.getTriggername() + "计划任务");

		}

	}

	/**
	 * 创建/添加计划任务
	 * 
	 * @param tbcq
	 *            计划任务配置对象
	 * @throws Exception
	 */
	public void createCronTriggerBean(Wsdoc tbcq) throws Exception {
		// 新建一个基于Spring的管理Job类
		MethodInvokingJobDetailFactoryBean mjdfb = new MethodInvokingJobDetailFactoryBean();
		mjdfb.setName(tbcq.getJobdetailname());// 设置Job名称
		// 如果定义的任务类为Spring的定义的Bean则调用 getBean方法
		if (tbcq.getIsspringbean().equals("1")) {
			mjdfb.setTargetObject(beanFactory.getBean(tbcq.getTargetobject()));// 设置任务类
		} else {
			// 否则直接new对象
			mjdfb.setTargetObject(Class.forName(tbcq.getTargetobject())
					.newInstance());// 设置任务类
		}

		mjdfb.setTargetMethod(tbcq.getMethodname());// 设置任务方法
		mjdfb.setConcurrent(tbcq.getConcurrent().equals("0") ? false : true); // 设置是否并发启动任务
		mjdfb.afterPropertiesSet();// 将管理Job类提交到计划管理类
		// 将Spring的管理Job类转为Quartz管理Job类
		JobDetail jobDetail = new JobDetail();
		jobDetail = (JobDetail) mjdfb.getObject();
		jobDetail.setName(tbcq.getJobdetailname());
		scheduler.addJob(jobDetail, true); // 将Job添加到管理类
		// 新一个基于Spring的时间类
		CronTriggerBean c = new CronTriggerBean();
		c.setCronExpression(tbcq.getCronexpression());// 设置时间表达式
		c.setName(tbcq.getTriggername());// 设置名称
		c.setJobDetail(jobDetail);// 注入Job
		c.setJobName(tbcq.getJobdetailname());// 设置Job名称
		scheduler.scheduleJob(c);// 注入到管理类
		scheduler.rescheduleJob(tbcq.getTriggername(), Scheduler.DEFAULT_GROUP,
				c);// 刷新管理类
		log.info(new Date() + ": 新建" + tbcq.getTriggername() + "计划任务");
	}

	public Scheduler getScheduler() {
		return scheduler;
	}

	public void setScheduler(Scheduler scheduler) {
		this.scheduler = scheduler;
	}

	public void setBeanFactory(BeanFactory factory) throws BeansException {
		this.beanFactory = factory;

	}

	public BeanFactory getBeanFactory() {
		return beanFactory;
	}
   
}
4.测试类代码

package com.framework.timer;

import java.util.Date;

import org.quartz.SchedulerException;



public class ISCSynAllData{  
	
	public void run() throws SchedulerException{
    	 System.out.println("开始执行"+new Date());
  
     }
}
5.Spring.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" 
	xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="
	http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
	http://www.springframework.org/schema/context 
	http://www.springframework.org/schema/context/spring-context-3.0.xsd
	http://www.springframework.org/schema/task   
	http://www.springframework.org/schema/task/spring-task-3.0.xsd
	">

	<!-- 引入属性文件 -->
	<context:property-placeholder location="classpath:config.properties" />

	<!-- 自动扫描dao和service包(自动注入) -->
	<context:component-scan base-package="com,cn" />
	
	<!-- 定时任务配置 实现方式1,利用spring自带的定时器
    <task:executor id="executor" pool-size="5" />   -->
    <!-- 声明一个具有10个线程的池,每一个对象将获取同样的运行机会
    <task:scheduler id="scheduler" pool-size="10" />   --> 
    <!--  定时器开关  开始
    <task:annotation-driven executor="executor" scheduler="scheduler" />-->
	<!--  定时器开关  结束-->
	<!--数据同步 -->
	<!--下面这种quartz定时器是为了实现人工对定时间的启用,停用,调用时间,和删除的操作  -->
<span style="color:#ff0000;"><!--实现方式二,利用 quartz实现定时器功能-->

<bean id="quartzManagerBean" class="com.framework.timer.QuartzManager">
		<property name="scheduler" ref="schedulerManager" />
	</bean>
	<bean id="quartzManagerJobDetail"
		class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
		<property name="targetObject" ref="quartzManagerBean" />
		<property name="targetMethod" value="reScheduleJob" />
		<property name="concurrent" value="false" />
	</bean>
	<!-- 主定时计划 -->
	<bean id="quartzManagerTrigger"
		class="org.springframework.scheduling.quartz.SimpleTriggerBean">
		<property name="jobDetail" ref="quartzManagerJobDetail" />
		<!-- 延时1分钟 执行任务 -->
		<property name="startDelay" value="300000" />
		<!-- 任务执行周期 5分钟 -->
		<property name="repeatInterval" value="60000" />
	</bean>
	<!-- 总管理类 如果将lazy-init='false'那么容器启动就会执行调度程序  -->
	<bean id="schedulerManager" lazy-init="false" autowire="no"
		class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<property name="triggers">
			<list>
				<ref bean="quartzManagerTrigger" />
			</list>
		</property>
	</bean>
</beans></span>
按照我以上配置流程把代码拷贝过去稍加修改即可实现!

demo代码下载地址:http://download.csdn.net/detail/wwkms/9152293

关于cronexpression时间表达式的说明,详见我的博客《Quartz CronTrigger最完整配置说明

  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值