2016-08-31 6 views
3

javascriptsetInterval(function, interval)/setTimeout(function, timeout)Spring Bootにしたいと思います。Spring Boot - Time.scheduleの代わりに?

私はfixedRate引数を持つ@Scheduled注釈を見つけましたが、アノテーションとして、私は動的にレートを変更することはできません(または私はできますか?)

今私はjava.util.Timerを使用していますのために、私はむしろ春を使用します。方法はありますか?

Schedulerインスタンスを取得し、動的に使用できますか?

ありがとうございました!

答えて

0

私の場合に適した解決策が見つかりました。 Main.javaで

:サービスで

@SpringBootApplication 
@ConfigurationProperties 
@EnableScheduling 
public class Main { 
    @Bean 
    ThreadPoolTaskScheduler taskScheduler() { 
     return new ThreadPoolTaskScheduler(); 
    } 

    public static void main(String[] args) { 
     SpringApplication.run(Main.class, args); 
    } 
} 

。java(残りのコントローラから呼び出される):

@Service 
public class Service { 
    private static final Logger log = LoggerFactory.getLogger(Service.class); 
    private final TaskScheduler scheduler; 

    @Autowired 
    public Service(TaskScheduler scheduler) { 
     this.scheduler = scheduler; 
    } 

    public void startTask(int inteval) { 
     scheduler.schedule(() -> log.info("Doing work"), triggerContext -> { 
      if (some_condition) { 
       ZonedDateTime now = ZonedDateTime.now(); 

       return Date.from(now.plusSeconds(interval).toInstant()); 
      } else { 
       // Stop the execution 
       return null; 
      } 
     }); 
    } 
} 

この解決策は機能しますが、正しい方法であるとは確信できません。

下記のコメントをお寄せいただきありがとうございます。私が参考になった提案があれば、解決策を変更する可能性があります。

2

Triggerを使用すると、次の実行を動的に制御できます。コメント回答する

Scheduling a job with Spring programmatically (with fixedRate set dynamically)

EDIT:あなたは別の答えはまさにこれをカバーし、SchedulingConfigurerを実装する必要が

nextExecutionTimeは(タスク次回に呼ばれ、およびオン...されており、あなたがする必要があるのは、このnumberOfMillisecondsBeforeCallingTheTask値の茶を持っている

nextExecutionTime.setTime(lastActualExecutionTime != null ? lastActualExecutionTime : new Date()); 
nextExecutionTime.add(Calendar.MILLISECOND, numberOfMillisecondsBeforeCallingTheTask); 

:nextExecutionTime)と呼ばれているが、このによって定義されますnged。

例:動的値MyController.triggerDelayを次の実行のために使用される方法

@RestController 
public class MyController { 

    public static int triggerDelay = 1000; 

    @RequestMapping("/changetrigger/{val}") 
    public void test(@PathVariable int val){ 
     this.triggerDelay = val; 
    } 
} 
@SpringBootApplication 
@EnableScheduling 
public class Launcher implements SchedulingConfigurer{ 

    public static void main(String[] args){ 
     new SpringApplicationBuilder() // 
     .sources(Launcher.class)// 
     .run(args); 
    } 

    @Bean(destroyMethod = "shutdown") 
    public Executor taskExecutor() { 
     return Executors.newScheduledThreadPool(100); 
    } 

    @Override 
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { 
     taskRegistrar.setScheduler(taskExecutor()); 
     ; 
     taskRegistrar.addTriggerTask(new TriggerTask(new Runnable() { 
      @Override 
      public void run() { 
       System.out.println("blah"); 
       System.out.println(System.currentTimeMillis()); 
      } 
     }, new Trigger() { 
      @Override 
      public Date nextExecutionTime(TriggerContext triggerContext) { 
       Calendar nextExecutionTime = new GregorianCalendar(); 
       nextExecutionTime.setTime(new Date()); 
       nextExecutionTime.add(Calendar.MILLISECOND, MyController.triggerDelay); 
       System.out.println(System.currentTimeMillis()); 
       return nextExecutionTime.getTime(); 
      }})); 
    } 
} 

注意。したがって、番号を変更すると、次の実行時間が変更されます。ブレークポイントをnextExecutionTimeの中に置くかどうかがわかります。

+0

見た目はいいですが、アプリケーションの起動時にのみ実行されます。常にスケジュールされたタスクを開始して停止する必要がある –

+0

は動的な理由を説明するために答えを更新しました – alexbt

+0

解決策を見つけましたが、それは少し異なります。おそらく私のニーズに適しています。私は投票し、私はそれについてのフィードバックを得るために私自身の解決策を追加します。ありがとう! –

0

あなただけのプロパティを外部化された上記、spring.boot.schedule.rateapplication.properties

spring.boot.schedule.rate = 5000

誤解問題の外部プロパティは、あなたの場合、用@Scheduled(fixedRateString = "${spring.boot.schedule.rate}")を使用することができます。ダイナミックな解決策については

、多分これはannonationでSPELを使用して、作業する必要があります:

@Service 
public class ScheduledService { 
    @Autowired 
    private FixRateProperty fixRateProperty; 

    @Scheduled(fixedRateString = "#{fixRateProperty.fixRate}") 
    private void reportCurrentTime() { 
     System.out.println(new Date());; 
    } 
} 

これには、あなたがプロパティでレートを外部化することができますFixRateProperty

@Component 
public class FixRateProperty { 
    private Long fixRate = 500L; 

    public Long getFixRate() { 
     return fixRate; 
    } 

    public void setFixRate(Long fixRate) { 
     this.fixRate = fixRate; 
    } 
} 

ですfixRateをどこかに設定してください。

+0

これは動的な解決策ではありません。アプリケーション開始時に決定され、グローバル定数です。異なるスケジュールで複数のタスクを実行したい場合、それは機能しません。 –

+0

@Algosub申し訳ありませんが、私は答えを更新します、これがあなたを助けてくれることを願っています。 –

+0

これはまだ私が必要なものではありません。私が投稿した答えを見てください、それは私が必要なものを明確にするかもしれません。私の解決策が良いかどうかはわかりませんが、それは私のために働きます。あなたはそれにコメントすることを歓迎し、私は提案に開放されています。 –