如何改变Spring的@Scheduled FIXEDDELAY在运行时(How to change

2019-07-21 02:20发布

我必须在固定的时间间隔运行批作业的要求,必须改变这个批处理作业的时间在运行时的能力。 为此,我遇到了Spring框架下提供@Scheduled注解。 但我不知道我怎么会在运行时更改FIXEDDELAY的价值。 我做了一些谷歌上搜索周围,但没有发现任何有用的东西。

Answer 1:

您可以使用Trigger来动态地设置下一个执行时间。 看到这里我的答案:

编程调度和春天有个任务(与固定利率动态设置)



Answer 2:

在春天开机,就可以直接使用应用程序的财产!

例如:

@Scheduled(fixedDelayString = "${my.property.fixed.delay.seconds}000")
private void process() {
    // your impl here
}

请注意,您也可以在案件没有定义属性的默认值,例如有“60”(秒),默认:

@Scheduled(fixedDelayString = "${my.property.fixed.delay.seconds:60}000")

其他的事情,我发现:

  • 该方法必须是void
  • 该方法必须没有参数
  • 该方法可以是private

我发现能够使用private的知名度得心应手,以这种方式使用它:

@Service
public class MyService {
    public void process() {
        // do something
    }

    @Scheduled(fixedDelayString = "${my.poll.fixed.delay.seconds}000")
    private void autoProcess() {
        process();
    }
}

作为private ,预定的方法可以是本地的为您服务,而不是成为你服务的API的一部分。

此外,该方法允许process()方法返回的值,其中@Scheduled方法可能没有。 例如,你的process()方法如下所示:

public ProcessResult process() {
    // do something and collect information about what was done
    return processResult; 
}

提供有关处理过程中所发生的一些信息。



Answer 3:

创建界面,这样的事情:

    public abstract class DynamicSchedule{
        /**
         * Delays scheduler
         * @param milliseconds - the time to delay scheduler.
         */
        abstract void delay(Long milliseconds);

        /**
         * Decreases delay period
         * @param milliseconds - the time to decrease delay period.
         */
        abstract void decreaseDelayInterval(Long milliseconds);

        /**
         * Increases delay period
         * @param milliseconds - the time to increase dela period
        */
        abstract void increaseDelayInterval(Long milliseconds);
}

接下来,让我们实现一个位于在春天上下文项目org.springframework.scheduling触发接口。

import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;

import java.util.Date;
import java.util.concurrent.ScheduledFuture;

public class CustomDynamicSchedule extends DynamicSchedule implements Trigger {

    private TaskScheduler taskScheduler;
    private ScheduledFuture<?> schedulerFuture;

    /**
     * milliseconds
     */
    private long delayInterval;

    public CustomDynamicSchedule(TaskScheduler taskScheduler) {
        this.taskScheduler = taskScheduler;
    }


    @Override
    public void increaseDelayInterval(Long delay) {
        if (schedulerFuture != null) {
            schedulerFuture.cancel(true);
        }
        this.delayInterval += delay;
        schedulerFuture = taskScheduler.schedule(() -> { }, this);
    }

    @Override
    public void decreaseDelayInterval(Long delay) {
        if (schedulerFuture != null) {
            schedulerFuture.cancel(true);
        }
        this.delayInterval += delay;
        schedulerFuture = taskScheduler.schedule(() -> { }, this);
    }

    @Override
    public void delay(Long delay) {
        if (schedulerFuture != null) {
            schedulerFuture.cancel(true);
        }
        this.delayInterval = delay;
        schedulerFuture = taskScheduler.schedule(() -> { }, this);
    }

    @Override
    public Date nextExecutionTime(TriggerContext triggerContext) {
        Date lastTime = triggerContext.lastActualExecutionTime();
        return (lastTime == null) ? new Date() : new Date(lastTime.getTime() + delayInterval);
    }
}

现在配置:

@Configuration
public class DynamicSchedulerConfig {
    @Bean
    public CustomDynamicSchedule getDinamicScheduler() {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
        threadPoolTaskScheduler.initialize();
        return  new CustomDynamicSchedule(threadPoolTaskScheduler);
    }
}

与用法:

@EnableScheduling
@Component
public class TestSchedulerComponent {

    @Autowired
    private CustomDynamicSchedule dynamicSchedule;

    @Scheduled(fixedDelay = 5000)
    public void testMethod() {
        dynamicSchedule.delay(1000l);
        dynamicSchedule.increaseDelayInterval(9000l);
        dynamicSchedule.decreaseDelayInterval(5000l);
    }

}


Answer 4:

AFAIK春天API不会让你访问你需要改变触发的内部。 但是,你可以改为手动配置豆类:

<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
    <property name="jobDetail" ref="jobDetail" />
    <property name="startDelay" value="10000" />
    <property name="repeatInterval" value="50000" />
</bean>

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
        <list>
            <ref bean="simpleTrigger" />
        </list>
    </property>
</bean>

然后,作为记录在SchedulerFactoryBean来:

在运行时的工作动态注册,使用一个bean参照本的SchedulerFactoryBean去Quartz调度(直接访问org.quartz.Scheduler )。 这允许你创造新的就业机会和触发器,以及控制和监视整个计划。



文章来源: How to change Spring's @Scheduled fixedDelay at runtime