WAS를 이용해서 주기적으로 특정 프로그램 실행하는 방법이 spring에서는 2가지가 있다. (뭐 더 있을수도 있다 -_-)
하나는 spring batch이고 다른 하나는 quartz를 이용하는 방법이다.
뭐가좋은지는 나도 잘 모른다. 일단 quartz가 어떤식으로 동작하는지 먼저 공부했으므로 이것부터 글 적는다.
1. 샘플 프로젝트 생성
STS 에서 [File] - [New] - [Spring Template Project] 메뉴를 클릭한 후 Spring MVC Project를 이용해 샘플 프로젝트를 생성한다.
2. pom.xml 파일 수정
quartz 관련 모듈을 이용하기 위해서 pom.xml 파일에 관련 라이브러리들 넣는다.
spring-tx, quartz, commons-collections, javax.transaction 4개 넣어줘야한다.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- Quartz framework and dependencies -->
<dependency>
<groupId>opensymphony</groupId>
<artifactId>quartz</artifactId>
<version>1.6.3</version>
<scope>compile</scope>
</dependency>
<!-- Quartz 1.6.0 depends on commons collections -->
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.1</version>
<scope>runtime</scope>
</dependency>
<!-- Quartz 1.6.0 requires JTA in non J2EE environments -->
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
<scope>runtime</scope>
</dependency>
3. 주기적으로 실행 될 Bean 생성
2개의 Bean을 만든다.
CronQuartz1.java
package com.mungchung.sample;
import java.text.SimpleDateFormat;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class CronQuartz1 extends QuartzJobBean{
@Override
protected void executeInternal(JobExecutionContext arg0)
throws JobExecutionException {
long time = System.currentTimeMillis();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
System.out.println("Cron trigger 1 (5 second): current time = " + sdf.format(time));
}
}
CronQuartz2.java
package com.mungchung.sample;
import java.text.SimpleDateFormat;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class CronQuartz2 extends QuartzJobBean{
@Override
protected void executeInternal(JobExecutionContext arg0)
throws JobExecutionException {
long time = System.currentTimeMillis();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
System.out.println("Cron trigger 2 (1 minute): current time = " + sdf.format(time));
}
}
4. quartz Bean과 위에서 생성한 Bean 연동
2개의 Bean이 각각 다른 시간차이로 실행되도록 설정해줄것이다.
CronQuartz1.java - 5초마다 실행
CronQuartz2.java - 1분마다 실행
/src/main/webapp/WEB-INF/spring/root-context.xml
<!-- 1. Cron 대상이 되는 클래스 정의 -->
<bean id="cronQuartz1" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.mungchung.sample.CronQuartz1"/>
</bean>
<bean id="cronQuartz2" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.mungchung.sample.CronQuartz2"/>
</bean>
<!-- 2. Cron 시간 설정 -->
<bean id="cronTrigger1" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="cronQuartz1"/>
<property name="cronExpression" value="0/5 * * * * ?"/>
</bean>
<bean id="cronTrigger2" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="cronQuartz2"/>
<property name="cronExpression" value="0 0/1 * * * ?"/>
</bean>
<!-- 3. Cron 실행 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger1"/>
<ref bean="cronTrigger2"/>
</list>
</property>
<property name="quartzProperties">
<props>
<prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
<prop key="org.quartz.threadPool.threadCount">3</prop>
<prop key="org.quartz.threadPool.threadPriority">4</prop>
<prop key="org.quartz.jobStore.class">org.quartz.simpl.RAMJobStore</prop>
<prop key="org.quartz.jobStore.misfireThreshold">60000</prop>
</props>
</property>
</bean>
Cron Expression
총 7개의 필드 있고 마지막 필드(년도)는 생략 가능하다
필드이름 |
허용 값 |
초(Seconds) |
0 ~ 59 |
분(Minutes) |
0 ~ 59 |
시간(Hours) |
0 ~ 23 |
달의 날짜(Day-of-month) |
1 ~ 31 |
달(Month) |
1 ~ 12 or JAN ~ DEC |
주의 날짜(Day-of-week) |
1 ~ 7 or SUN-SAT |
년도(Year) (선택가능) |
빈값, 1970 ~ 2099 |
Cron Expression의 특수문자
Expression |
설명 |
예시 |
* |
모든 수를 나타냄 |
|
- |
값의 사이를 의미 |
* 10-13 * * * * 10,11,12,13분에 동작함 |
, |
특정값 지칭 |
* 10,11,13 * * * * 10,11,13분에 동작함 |
/ |
값의 증가를 표현 |
* 0/5 * * * * 0분부터 시작해서 5분마다 동작 |
? |
특별한 값이 없음을 나타냄(day-of-month, day-of-week 필드만 사용) |
|
L |
마지막 날을 나타냄(day-of-month, day-of-week 필드만 사용) |
|
6. 실행결과
실행결과를 보면 하나는 5초마다, 다른 하나는 1분마다 Bean이 실행되고 있음을 알수 있다.

스케쥴로 디비에 접근하고 싶은데 방법이 따로 있나요?
jdbc방법을 사용했더니 IO 오류가 첫 실행 이후 두뻔째 실행 부터 나옵니다..
DAO에 바로 접속했더니 SqlSessionDaoSupport를 상속 받지 못해서 불러 오지도 못하고 있고요