容易修改quartz支持动态修改执行时间和集群架构

简单修改quartz支持动态修改执行时间和集群架构

需求:

1.可以通过数据库配置cronExpression表达式,动态修改执行时间

2.不修改服务器环境支持集群架构:即保证集群环境下单实例运行

3.实现业务上的实时开启/停止控制功能

 

第一步:建立数据表

create table SCHEDULER_CONF
(
  TRIGGER_NAME   VARCHAR2(64) not null,
  SCHEDULER_NAME VARCHAR2(100) not null,
  CRON_EXPR      VARCHAR2(64) not null,
  STATUS         CHAR(1) not null,--激活状态
  RUN_STATUS     CHAR(1),--当前运行状态
  CONSTRAINT "T_PK" PRIMARY KEY ("TRIGGER_NAME")
)

 第二步:实现基础控制类

public abstract class BaseSchedulerBean {
    
    private String triggerName;
    
    protected static Scheduler scheduler;
    protected static JdbcTemplate jdbcTemplate;
    
    protected static JdbcTemplate getJdbcTemplate() {
        if(jdbcTemplate == null){
            jdbcTemplate = InstanceFactory.getInstance(JdbcTemplate.class);
        }
        return jdbcTemplate;
    }

    public static Scheduler getScheduler() {
        if(scheduler == null)scheduler = InstanceFactory.getInstance(Scheduler.class);
        return scheduler;
    }
    
   
    public void setTriggerName(String triggerName) {
        this.triggerName = triggerName;
    }

    public synchronized void execute(){
        try {
            String latestConExpr = checkExecutable(triggerName);
            if(latestConExpr == null)return;
            
            updateExecutable(true); 
            
            doJob();
            
            checkConExpr(latestConExpr);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            updateExecutable(false); 
        }
        
    }
    
    public void checkConExpr(String latestConExpr) {
        try {
            //check cronExpr valid
            CronTriggerBean trigger = (CronTriggerBean) getScheduler().getTrigger(
                    triggerName, Scheduler.DEFAULT_GROUP);
            String originConExpression = trigger.getCronExpression();
            //判断任务时间是否更新过
            if (!originConExpression.equalsIgnoreCase(latestConExpr)) {
                trigger.setCronExpression(latestConExpr);
                getScheduler().rescheduleJob(triggerName, Scheduler.DEFAULT_GROUP, 
                        trigger);
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
       
    }
    
    /**
     * 检测当前是否可用:激活状态=Y,运行状态=N<br>
     * generate by: vakin jiang
     *                    at 2012-2-13
     * @return
     */
    protected String checkExecutable(String triggerName){
        String conExpr = null;
        try {
            SqlRowSet rs = getJdbcTemplate().queryForRowSet("SELECT CRON_EXPR FROM SCHEDULER_CONF WHERE STATUS='Y' and RUN_STATUS='N' and TRIGGER_NAME='"+triggerName+"'");
            if(rs.next()){
                conExpr = rs.getString("CRON_EXPR");
            }
        } catch (Exception e) {}
        return conExpr;
    }
    
    /**
     * 更新运行状态<br>
     * generate by: vakin jiang
     *                    at 2012-2-13
     * @param runing
     */
    protected void updateExecutable(boolean runing){
        String status = runing ? "Y" :"N";
        String sql = "UPDATE SCHEDULER_CONF set RUN_STATUS='"+status+"' WHERE TRIGGER_NAME='"+triggerName+"'";
        getJdbcTemplate().execute(sql); 
    }
    
    public abstract void doJob();
    
}

 

以上两步就已经完成,下面就可以直接用了

public class DemoScheduler extends BaseSchedulerBean {
    /*
     *@see com.csair.scms.infrastructure.extend.quartz.BaseSchedulerBean#doJob()
     */
    @Override
    public void doJob() {
        //do something
    }
}

 

ps:spring配置可不做任何修改,当然也可以通过重写简化配置

      InstanceFactory为一个我们自己写好的spring实例工厂