当前位置: 首页 > 面试题库 >

如何在春季使用EnableScheduling批注在运行时重新启动计划的任务?

公孙慎之
2023-03-14
问题内容

我一直在研究如何使用Java
8和spring在运行时更改作业的频率。这个问题非常有用,但是并不能完全解决我的问题。

现在,我可以配置下次上班的日期。但是,如果将延迟设置为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";
    }

}

问题答案:
  1. 创建一个单例bean来注入TaskScheduler。这将持有的状态变量的所有ScheduledFuture小号,像private ScheduledFuture job1;
  2. 在部署时,从数据库加载所有计划数据并启动作业,并填充所有状态变量,例如job1
  3. 更改调度数据后,取消相应的Future(例如job1),然后使用新的调度数据重新启动它。

此处的关键思想是在Future创建s时对其进行控制,以便将其保存在某些状态变量中,以便在调度数据中的某些内容发生更改时,可以将其取消。

这是工作代码:

applicationContext.xml

<task:annotation-driven />
<task:scheduler id="infScheduler" pool-size="10"/>

单例bean,包含Futures

@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);
                }
        }
}


 类似资料:
  • 问题内容: 我在 Spring的任务计划程序中安排 了几个 任务 : 如何访问 计划任务列表 并从应用程序上下文中检索 元信息 (例如下一次执行时间)? 问题答案: Spring中没有公共API可以执行此操作。 有关: Spring对象在运行时如何表示?

  • 问题内容: 我已经使用Spring Framework的注释创建了一个简单的计划任务。 现在,当不再需要时,我想停止此任务。 我知道在此方法开始时可能有一种方法可以检查一个条件标志,但这不会停止执行此方法。 Spring提供了什么来停止任务? 问题答案: 选项1:使用后处理器 为应停止调度的bean 提供并显式调用。 选项2:维护目标豆与其未来的映射 当必须停止对bean的调度时,可以查找该映射以

  • 问题内容: 我正在尝试实现的是生成一个UUID,该UUID在数据库插入期间会自动分配。与名为“ id”的主键列相似,生成一个id值。 模型值看起来像这样: 但是当数据库插入完成时。“ uuid”为空。 非常感谢您的帮助。如果我问一个明显的愚蠢问题,对不起。 问题答案: 您可以使用诸如@PrePersist之类的事件来填充UUID字段 https://docs.jboss.org/hibernate

  • 我使用Spring Framework的注释创建了一个简单的计划任务。 我知道可以有一个选择在这个方法开始时检查一个条件标志,但这不会停止这个方法的执行。 Spring提供了什么来停止任务吗?

  • 问题内容: 我在Java文档中看到了这一点:ScheduledAtFixedRate,它说 如果该任务的任何执行遇到异常,将禁止后续执行 我不希望在我的应用程序中发生这种情况。即使看到异常,我也总是希望后续执行继续进行。我怎样才能从。 问题答案: 用try / catch包围Callable.call方法或Runnable.run方法… 例如: 请注意,捕获除编译器也告诉您的内容之外的其他内容(在

  • 我有一个spring boot应用程序,我需要每20秒刷新一次,所以我创建了这个: 它工作得很好,但当我向数据库中添加行时,在它为空之前,我想再次将计时器重置为20秒,有办法吗?