バッチジョブを一定の間隔で実行する必要があり、実行時にこのバッチジョブの時間を変更できます。このために、Springフレームワークで提供される@Scheduledアノテーションに出会いました。しかし、実行時にfixedDelayの値をどのように変更するかはわかりません。私はいくつかのグーグルを試しましたが、有用なものは見つかりませんでした。
Trigger
を使用して、次の実行時間を動的に設定できます。ここで私の答えを参照してください:
スプリングブートでは、アプリケーションプロパティを直接使用できます!
例えば:
_@Scheduled(fixedDelayString = "${my.property.fixed.delay.seconds}000")
private void process() {
// your impl here
}
_
プロパティが定義されていない場合は、デフォルト値を使用することもできます。たとえば、デフォルトの「60」(秒)を使用できます。
_@Scheduled(fixedDelayString = "${my.property.fixed.delay.seconds:60}000")
_
私が発見した他のこと:
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;
}
_
処理中に発生したことに関する情報を提供します。
インターフェースを作成し、そのようなもの:
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);
}
次に、spring-contextプロジェクトのorg.springframework.schedulingにあるTriggerインターフェースを実装しましょう。
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 getDynamicScheduler() {
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);
}
}
私の知る限り、Spring APIでは、トリガーを変更するために必要な内部にアクセスできません。ただし、代わりにBeanを手動で構成することもできます。
<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に記載されているように:
実行時にジョブを動的に登録するには、このSchedulerFactoryBeanへのBean参照を使用して、Quartz Scheduler(
org.quartz.Scheduler
)。これにより、新しいジョブとトリガーを作成したり、スケジューラ全体を制御および監視したりできます。