需求:
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实例工厂