加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 如何在Spring上运行EnableScheduling注释来重新启动计划

发布时间:2020-12-14 16:23:27 所属栏目:Java 来源:网络整理
导读:我一直在调查如何使用 Java 8和spring在运行时更改作业的频率. This question非常有用,但并没有完全解决我的问题. 我现在可以配置下次执行工作的日期.但是如果将延迟设置为1年,那么我需要等待1年才能考虑新的配置. 我的想法是如果配置值改变(因此从另一个类)
我一直在调查如何使用 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";
    }

}

解决方法

>创建一个获得注入 TaskScheduler的单例bean.这将保持为状态变量全部 ScheduledFutures,如私人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);
                }
        }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读