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에 추가되어 있어야 합니다.
테스트 코드
테스트 코드를 단순하게 만들기 위해서 크론표현식을 추출하고 검사하는 코드는 SpringCronExpressionTestUtils클래스로 분리했습니다.
package edu.batch.baseball.schedule;
import static edu.batch.support.launch.SpringcronExpressionTestUtils.*;
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 cronExpression = getcronExpressionOfMethod(BaseballScheduledJobLauncher.class, "baseballJob");
assertSchedule(cronExpression, initialTime, expectedTimeList,DATE_PATTERN);
}
}
SpringCronExpressionTestUtils
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 SpringCronExpressionTestUtils {
public static String getCronExpressionOfMethod(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 cronExpression = scheduleInfo.cron();
return cronExpression;
}
public static void assertSchedule(String cronExpression, String initialTime,
List<String> expectedTimeList, String datePattern) {
CronTrigger trigger = new CronTrigger(cronExpression);
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);
}
}
}
Twitter
Google+
Facebook
Reddit
LinkedIn
StumbleUpon
Email