JAVA & Open Framework2013. 5. 10. 10:39

Spring 3.0부터는 Quartz가 없이도 실행 스케쥴 설정이 가능합니다. 설정과 테스트 방법을 정리했습니다.

 

@Schedule 를 써서 크론 표현식 설정

  실행을 하고 싶은 메소드를 @Component, @Schedule annotaion을 통해 지정을 합니다.


@Component
public class BaseballScheduledJobLauncher extends JobLaunchSupport {

.....

    @Scheduled(cron="45 * * * * MON-FRI")
    public void baseballJob() {
        JobParameters params = createTimeParameter();
        run("baseballJob", params);
    }

   
    @Scheduled(cron="45 10 5 * * MON-FRI")
    public void baseballExportJob() {
        JobParameters params = createTimeParameter();
        run("baseballExportJob", params);
    }

}


 java 파일에 설정된 Annotation을 인식하기 위해서 Application context의 xml파일에 component-scan과 annotation으로 schedule을 설정하겠다는 선언을 추가합니다.  그리고 schedule을 실행할 thread pool의 크기도 지정합니다.


    <context:component-scan base-package="edu.batch.baseball.schedule"/>
    <task:scheduler id="myScheduler" pool-size="10"/>
    <task:annotation-driven scheduler="myScheduler"/>


 'task'와 'component'의 namespace가 xml에 추가되어 있어야 합니다.

테스트 코드

 테스트 코드를 단순하게 만들기 위해서 크론표현식을 추출하고 검사하는 코드는 SpringCronE-pressionTestUtils클래스로 분리했습니다.

 

package edu.batch.baseball.schedule;

import static edu.batch.support.launch.SpringCronE-pressionTestUtils.*;

import java.util.Arrays;
import java.util.List;

import org.junit.Test;

import edu.batch.baseball.schedule.BaseballScheduledJobLauncher;

public class BaseballScheduledJobLauncherTest {

    private static final String DATE_PATTERN = "yyyy/MM/dd hh:mm:ss";

    @Test
    public void testBaseballJobSchedule() {
        String initialTime = "2010/09/01 09:00:00";
        List<String> expectedTimeList = Arrays.asList(
                "2010/09/01 09:00:45",
                "2010/09/01 09:01:45",
                "2010/09/01 09:02:45");
        String cronE-pression = getCronE-pressionOfMethod(BaseballScheduledJobLauncher.class, "baseballJob");
        assertSchedule(cronE-pression, initialTime, expectedTimeList,DATE_PATTERN);
    }
}


 

 SpringCronE-pressionTestUtils

첨부파일 : SpringCronE-pressionTestUtils.java

 

package edu.batch.support.launch;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

import java.lang.reflect.Method;
import java.text.ParseException;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.scheduling.support.SimpleTriggerContext;

public class SpringCronE-pressionTestUtils {

 public static String getCronE-pressionOfMethod(Class<?> targetClass,
   String methodName)  {
  Method scheduledMethod;
  try {
   scheduledMethod = targetClass.getDeclaredMethod(methodName,
     new Class[] {});
  } catch (SecurityException e) {
   throw new IllegalArgumentException("cannot access the method : " + methodName, e);
  } catch (NoSuchMethodException e) {
   throw new IllegalArgumentException(e);
  }
  Scheduled scheduleInfo = scheduledMethod.getAnnotation(Scheduled.class);
  String cronE-pression = scheduleInfo.cron();
  return cronE-pression;
 }

 

public static void assertSchedule(String cronE-pression, String initialTime,
   List<String> expectedTimeList, String datePattern) {
  CronTrigger trigger = new CronTrigger(cronE-pression);
  Date startTime;
  try {
   startTime = DateUtils.parseDate(initialTime,
     new String[] { datePattern });
  } catch (ParseException e) {
   throw new IllegalArgumentException("wrong date format", e);
  }
  SimpleTriggerContext context = new SimpleTriggerContext();
  context.update(startTime, startTime, startTime);

  for (String exptectedTime : expectedTimeList) {
   Date nextExecutionTime = trigger.nextExecutionTime(context);
   String actualTime = DateFormatUtils.format(nextExecutionTime,
     datePattern);
   assertThat("executed on expected time", actualTime,
     is(exptectedTime));
   context.update(nextExecutionTime, nextExecutionTime,
     nextExecutionTime);
  }
 }

}

 

 

출처 : http://blog.benelog.net/2802946

Posted by 아로나