如何在XML配置的Spring Quartz调度中动态设置repeatInterval
解决方法
第一步:写个从数据库读配置的类
先搞个DAO类专门从数据库查repeatInterval的值:
public class ScheduleConfigDao { private JdbcTemplate jdbcTemplate; // 注入Spring的JdbcTemplate public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } // 从数据库里查对应任务的重复间隔(单位毫秒) public long getRepeatInterval() { String sql = "SELECT repeat_interval FROM schedule_config WHERE job_name = 'msgScheduledEventConsumers'"; return jdbcTemplate.queryForObject(sql, Long.class); } }
把这个DAO加到XML配置里:
<bean id="scheduleConfigDao" class="你的包名.ScheduleConfigDao"> <property name="jdbcTemplate" ref="jdbcTemplate" /> </bean>
第二步:自定义Trigger的工厂类
原来的SimpleTriggerFactoryBean没法动态读数据库值,我们自己写个FactoryBean来创建Trigger,在里面调用上面的DAO拿配置:
import org.quartz.SimpleTrigger; import org.quartz.Trigger; import org.springframework.beans.factory.FactoryBean; import org.springframework.scheduling.quartz.JobDetailAwareTrigger; public class DynamicSimpleTriggerFactoryBean implements FactoryBean<Trigger> { private JobDetailAwareTrigger trigger = new SimpleTrigger(); private ScheduleConfigDao scheduleConfigDao; private long startDelay; @Override public Trigger getObject() throws Exception { // 从数据库取重复间隔,设置到Trigger里 long repeatInterval = scheduleConfigDao.getRepeatInterval(); trigger.setRepeatInterval(repeatInterval); trigger.setStartDelay(startDelay); return trigger; } @Override public Class<?> getObjectType() { return SimpleTrigger.class; } @Override public boolean isSingleton() { return true; } // 注入JobDetail public void setJobDetail(org.quartz.JobDetail jobDetail) { trigger.setJobDetail(jobDetail); } // 注入读配置的DAO public void setScheduleConfigDao(ScheduleConfigDao scheduleConfigDao) { this.scheduleConfigDao = scheduleConfigDao; } // 设置启动延迟 public void setStartDelay(long startDelay) { this.startDelay = startDelay; } }
第三步:替换XML里的Trigger配置
把原来的SimpleTriggerFactoryBean换成我们自己写的这个工厂类:
<bean id="msgScheduledEventConsumersTrigger" class="你的包名.DynamicSimpleTriggerFactoryBean"> <property name="jobDetail" ref="msgScheduledEventConsumersJob" /> <property name="startDelay" value="60000" /> <property name="scheduleConfigDao" ref="scheduleConfigDao" /> </bean>
额外:支持运行时动态更新间隔
如果需要数据库改了值之后自动生效,就在你的groupChatNotificationService里注入调度器和配置DAO,每次执行任务时检查配置有没有变,变了就更新Trigger:
public class GroupChatNotificationService { private Scheduler scheduler; private ScheduleConfigDao scheduleConfigDao; private long lastSavedInterval; // 注入调度器 public void setScheduler(Scheduler scheduler) { this.scheduler = scheduler; } // 注入配置DAO,初始化时先读一次当前间隔 public void setScheduleConfigDao(ScheduleConfigDao scheduleConfigDao) { this.scheduleConfigDao = scheduleConfigDao; this.lastSavedInterval = scheduleConfigDao.getRepeatInterval(); } public void doNotify() { // 你的业务逻辑代码... // 检查数据库里的间隔有没有变 long currentInterval = scheduleConfigDao.getRepeatInterval(); if (currentInterval != lastSavedInterval) { try { SimpleTrigger trigger = (SimpleTrigger) scheduler.getTrigger("msgScheduledEventConsumersTrigger", Scheduler.DEFAULT_GROUP); trigger.setRepeatInterval(currentInterval); scheduler.rescheduleJob("msgScheduledEventConsumersTrigger", Scheduler.DEFAULT_GROUP, trigger); lastSavedInterval = currentInterval; } catch (SchedulerException e) { // 这里记得处理异常,比如打日志 e.printStackTrace(); } } } }
这样既保留了XML配置的方式,避开注解调度重复执行的坑,又实现了从数据库动态获取并设置重复间隔的需求。
内容的提问来源于stack exchange,提问作者d00d
相关产品推荐
相关产品推荐

