2016-08-31 3 views
3

javascriptsetInterval(function, interval)/setTimeout(function, timeout)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)

편집 : 당신은 SchedulingConfigurer를 구현해야, 다른 대답은 정확히이 포함

nextExecutionTime가 계속적으로 호출되고 ... 다음에 작업을 (그리고 nextExecutionTime)은이에 의해 정의된다라고 : 당신이해야 할 모든이 numberOfMillisecondsBeforeCallingTheTask 값의 차를 가지고있다

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

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

이것은 여전히 ​​내가 필요한 것이 아닙니다. 제가 게시 한 답변을 보시고, 제가 필요한 것을 분명히 해줄 수 있습니다. 내 솔루션이 좋은 것인지 모르겠지만, 저에게는 효과적입니다. 당신은 그것에 대해 환영 할 만하며 제안은 받아 들일 수 있습니다. –