我一直在调查如何使用
Java 8和spring在运行时更改作业的频率.
This question非常有用,但并没有完全解决我的问题.
我现在可以配置下次执行工作的日期.但是如果将延迟设置为1年,那么我需要等待1年才能考虑新的配置.
我的想法是如果配置值改变(因此从另一个类),停止计划的任务.然后重新计算下一次执行任务时.也许有更简单的方法来做到这一点.
这是我到目前为止的代码.
@Configuration @EnableScheduling public class RequestSchedulerConfig implements SchedulingConfigurer { @Autowired SchedulerConfigService schedulerConfigService; @Bean public RequestScheduler myBean() { return new RequestScheduler(); } @Bean(destroyMethod = "shutdown") public Executor taskExecutor() { return Executors.newScheduledThreadPool(100); } @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.setScheduler(taskExecutor()); taskRegistrar.addTriggerTask( new Runnable() { @Override public void run() { myBean().startReplenishmentComputation(); } },new Trigger() { @Override public Date nextExecutionTime(TriggerContext triggerContext) { Duration d = schedulerConfigService.getIntervalFromDB(); return DateTime.now().plus(d).toDate(); } } ); } }
这将是我想做的.
@RestController @RequestMapping("/api/config/scheduler") public class RequestSchedulerController { @Autowired ApplicationConfigWrapper applicationConfigWrapper; @RequestMapping("/set/") @ResponseBody public String setRequestSchedulerConfig(@RequestParam(value = "frequency",defaultValue = "") final String frequencyInSeconds){ changeValueInDb(frequencyInSeconds); myJob.restart(); return "Yeah"; } }
解决方法
>创建一个获得注入
>在部署时,从数据库加载所有调度数据并启动作业,填充所有状态变量,如job1.
>关于调度数据的更改,cancel将对应的Future(例如job1),然后再次使用新的调度数据启动它.
TaskScheduler
的单例bean.这将保持为状态变量全部
ScheduledFuture
s,如私人ScheduledFuture job1;
>在部署时,从数据库加载所有调度数据并启动作业,填充所有状态变量,如job1.
>关于调度数据的更改,cancel将对应的Future(例如job1),然后再次使用新的调度数据启动它.
这里的主要思想是在创建Futures时获取控制权,以便将它们保存在一些状态变量中,这样当调度数据中的某些事物发生变化时,您可以取消它们.
这是工作代码:
applicationContext.xml中
<task:annotation-driven /> <task:scheduler id="infScheduler" pool-size="10"/>
单身豆,持有期货
@Component public class SchedulerServiceImpl implements SchedulerService { private static final Logger logger = LoggerFactory.getLogger(SchedulerServiceImpl.class); @Autowired @Qualifier(value="infScheduler") private TaskScheduler taskScheduler; @Autowired private MyService myService; private ScheduledFuture job1;//for other jobs you can add new private state variables //Call this on deployment from the ScheduleDataRepository and everytime when schedule data changes. @Override public synchronized void scheduleJob(int jobNr,long newRate) {//you are free to change/add new scheduling data,but suppose for now you only want to change the rate if (jobNr == 1) {//instead of if/else you could use a map with all job data if (job1 != null) {//job was already scheduled,we have to cancel it job1.cancel(true); } //reschedule the same method with a new rate job1 = taskScheduler.scheduleAtFixedRate(new ScheduledMethodRunnable(myService,"methodInMyServiceToReschedule"),newRate); } } }