spring 3.2.2부터 Scheduled에 String 문자열로 간단한 문자열 형태를 받을 수 있어 크론 잡을 실행할 수 있었다. 



https://github.com/spring-projects/spring-framework/blob/master/spring-context/src/main/java/org/springframework/scheduling/annotation/Scheduled.java


/**

* Execute the annotated method with a fixed period in milliseconds between the

* end of the last invocation and the start of the next.

* @return the delay in milliseconds as a String value, e.g. a placeholder

* @since 3.2.2

*/

String fixedDelayString() default "";



http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/scheduling/annotation/Scheduled.html#fixedDelayString--



spring 3.2.2부터 fixedDelayString, fixedRateString, initialDelayString 을 사용할 수 있다. 



https://github.com/spring-projects/spring-framework/blob/3.2.x/spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java



즉, 아래와 같은 코드를 사용할 수 있다. 

@Scheduled(fixedDelayString="10")


@Scheduled(fixedRate = 10)



annotation 레벨에서 fixedDelayString을 사용하려면 다음 테스트 코드를 사용해 테스트해 볼 수 있다.




private AnnotationConfigApplicationContext ctx;

@Test

public void ScheduleTest() throws InterruptedException {

  ctx = new AnnotationConfigApplicationContext(TestScheduleClass.class);


  Thread.sleep(10);

  assertThat(ctx.getBean(AtomicInteger.class).get(), greaterThanOrEqualTo(1));

}


@Configuration

@EnableScheduling

private static class TestScheduleClass {

  public TestScheduleClass() {}


    @Bean

  public AtomicInteger counter() {

    return new AtomicInteger();

  }


  @Scheduled(fixedDelayString="10")

  public void run() {

    new Integer(10);

    int a = counter().incrementAndGet();

    System.out.println("xxxx : " + new Date() + "," + a);

  }

}




간단한 property 또는 아주 간단한 spel(예, properties 파일에서 읽은 설정) 등이 될 것이다.


private static final String delay = "new Integer(10)";

@Scheduled(fixedDelayString=delay)



@Scheduled(fixedDelayString="${fix.Delay}")


그러나, @Scheduled에 fixedDelayString에 SPEL을 사용하려면 에러가 발생한다.


@Scheduled(fixedDelayString="#{new Integer(10)}")



예외는 다음과 같다.


Caused by: java.lang.IllegalStateException: Encountered invalid @Scheduled method 'run': Invalid fixedDelayString value "#{new Integer(10)}" - cannot parse into integer

at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor$1.doWith(ScheduledAnnotationBeanPostProcessor.java:259)

at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:495)

at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:502)

at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:473)

at 






spring 3.x에서는 @Scheduled에 spel을 사용할 수 없다.




따라서 @Schedule에 spel을 사용하려면 Spring 4.3.0을 써야 한다. (SPEL 처리하는 아래 Resolver가 추가되었다..)


https://github.com/spring-projects/spring-framework/blob/master/spring-beans/src/main/java/org/springframework/beans/factory/config/EmbeddedValueResolver.java






@Scheduled(fixedRate = 6000, initialDelayString = #{ T(java.lang.Math).random() * 10 } )




Posted by '김용환'
,