您的位置:首页 > 编程语言 > Java开发

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

2018-03-23 13:49 881 查看
由于公司的新接得项目要实现一批数据的同步,通过外围厂商提供的一系列各个系统的webervices接口定时将数据同步到我们开发的共享平台上,由于厂商系统的数据是不断在变化以及各系统闲忙时的特点,所以定时同步任务的执行必须在时间上能够动态配置。因此,我们需要动态的从数据库中获取配置信息,以改变各个定时间的执行规则,废话不说了,上代码:(我利用的是ssh框架直接写的,框架搭建不再叙述)1.创建数据表(我用的是mysql)[sql] view plain copyDROP 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;  
[sql] view plain copyINSERT 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.创建表对应的实体类[java] view plain copypackage ...自定义;  
  
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代码 [java] view plain copypackage 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(); //从数据库中获取所有的配置信息,根据自己的获取方式来写,此不赘述  
[java] view plain copy               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.测试类代码[java] view plain copypackage 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中的配置(标红的为核心配置)[html] view plain copy<?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>  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐