Scheduling Service

Spring Framework는 scheduling을 사용하기 위한 통합클래스를 가지고있다. 현재, Spring는 JDK 1.3이후 제공되는 Timer Scheduler와 the Quartz Scheduler( http://www.opensymphony.com/quartz/)를 제공한다. Quartz 는 오픈 소스 작업 스케줄링 프레임워크이다. Quartz는 완전히 자바로 작성되어 있으며, J2SE와 J2EE 어플리케이션 모두에서 사용될 목적으로 설계되었다. Quartz는 매우 유연하며 단순한 구조를 제공한다. 간단한 작업은 물론 복잡한 작업 모두에 대한 스케줄링을 작성할 수 있다. Quartz는 또한 EJB, JavaMail 등을 위한 데이터베이스 지원, 클러스터링, 플러그 인, 미리 내장된 작업들을 포함하고 있으며, cron과 유사한 표현식도 지원한다.
Anyframe Core에서는 JDK의 Timer Scheduler보다 Quartz Scheduler 사용을 추천한다. Quartz Scheduler는 JDK Timer Scheduler보다 더 유동성있고 성능이 좋다. 자세한 내용은 Spring 매뉴얼의 Scheduling 부분 을 참고하도록 한다.

Quartz Scheduler

Quartz는 Trigger, Job 그리고 모든 종류의 jobs를 인식하고 있는 JobDetail을 사용한다. Quartz에 깔려 있는 기본적인 개념을 알고 싶다면, http://www.opensymphony.com/quartz 를 참고한다.
아래 예제에서는
  • SchedulerFactoryBean : 사용되는 Trigger를 생성시켜주는 역할을 담당하므로 Trigger들을 triggers attribute의 list 태그 하위로 등록시켜 놓는다.
  • SimpleTriggerBean : 언제, 어떻게 JOB를 실행하는지에 대해 정의된 매커니즘으로 Spring은 편의를 위해 2개의 상속받은 Trigger를 기본적으로 제공한다. ( SimpleTriggerBean , CronTriggerBean)
  • MethodInvokingJobDetailFactoryBean : scheduler에 맞춰서 객체의 메소드를 호출할 필요가 있을 때 사용한다.
을 사용하여 일정한 시간 간격 마다 targetMethod이 실행되도록 설정하는 방법을 보여주고 있다.
다음은 SimpleTriggerBean의 속성으로 정의되어야 할 항목들에 대한 설명이다.
Property Name
Description
Required
Default Value
jobDataAsMap 주어진 Map의 JobDataMap에서 Object를 등록한다. 다른 object와는 다르게 이 object들은 JobDetail의 data map에서 이 Trigger만 이용할 수 있다. N N/A
misfireInstructionName SimpleTrigger class에서 대응되는 상수 name를 통한 instruction이 실패한 경우 설정한다. N MISFIRE_INSTRUCTION_SMART_POLICY
triggerListenerNames Scheduler에 등록된 non-global TriggerListeners을 설정한 job의 TriggerListener name의 list를 설정한다. TriggerListener name는 항상 TriggerListener implementation에 의해 리턴된 name를 지시한다.. N N/A
startDelay 처음 job이 시작되기 전에 지연시간을 설정한다. 입력 한 milliseconds 단위의 시간에 현재시간을 더하면 시작시간이 된다. 시간 지연은 사용자가 시작 시간을 정하지 않으면 시간 지연은 적용된다. 그러나 Spring context안에서 전형적으로 사용할 때 시작 시간은 언제든지 Container가 시작되는 시간일 것이다. 이 경우에는 상대적인 시간 지연을 열거하는 것이 좋다. N 0
jobDetail 이 trigger와 관련된 JobDetail을 설정한다. JobDetail이 Spring-managed bean일 경우 bean reference와 함께 사용된다. 대신 trigger는 name과 group을 통해 job와 연관될 수 있다. N N/A
repeatCount SimpleTrigger가 반복될 수를 설정한다. 반복 된 후 자동으로 삭제 된다. N N/A
endTime SimpleTrigger 반복이 끝나는 시간을 입력한다. (그리고 종료 후 자동으로 삭제된다.) N N/A
repeatInterval SimpleTrigger가 반복되는 interval 시간을 milliseconds 단위로 설정한다. repeatInterval은 0보다 커야 한다. N N/A
timesTriggered SimpleTrigger가 시작된 시간을 설정한다. N N/A

다음은 MethodInvokingJobDetailFactoryBean의 속성으로 정의되어야 할 항목들에 대한 설명이다.
Property Name
Description
Required
Default Value
name job의 이름을 설정한다. N FactoryBean의 Bean name
targetObj 참조할 object의 명을 정의 해준다. N
targetMethod targetObj에서 설정한 Object에서 실행하고자 하는 method 명을 입력한다. N
group job의 그룹을 설정한다. N the Scheduler의 그룹
concurrent multiple jobs이 동시에 실행되는지 지정한다. N true
targetBeanName Spring BeanFactory에서 target bean을 설정한다. non-singleton beans을 실행하기 위해 targetObject를 이용할 때 정의한다. 정의한 "targetObject"과 "targetClass"의 값은 "targetBeanName"에 대응되는 값으로 오버라이드 될 수 있다. (i.e. 정적으로 미리정의된 bean type나 bean object) N N/A

Samples

다음은 일정 시간 마다 executeObj에 정의된 class의 executeMethod를 반복해서 실행하는 Scheduling Service의 예이다.
  • Configuration
  • 다음은 Scheduling Service의 속성 파일인 applicationContext-scheduling.xml의 일부이다. repeatInterval을 1000, repeatCount를 5로 설정했기 때문에 executeObj에서 실행할 Object의 executeMethod를 1000밀리세컨드마다 5번 반복 실행한다.
    <bean id="schedulerFactoryBean" 
    		class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    	<property name="triggers">
    		<list>
    			<ref local="simpleTrigger"/>
    		</list>
    	</property>		
    </bean>	
    
    <bean id="simpleTrigger"
        class="org.springframework.scheduling.quartz.SimpleTriggerBean">
    	<property name="jobDetail" ref="jobDetail" />
    	<property name="repeatInterval" value="1000"/>
    	<property name="repeatCount" value="5"/>
    </bean>
    
    <bean id="jobDetail" 
        class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    	<property name="targetObject" ref="executeObj"/>
    	<property name="targetMethod" value="executeMethod"/>
    </bean>
    
    <bean id="executeObj"
        class="integration.anyframe.services.scheduling.SchedulingServiceExecute"/>
  • TestCase
  • 다음은 앞서 정의한 속성 설정을 기반으로 하여 schedule를 실행하는 SchedulingServiceTest.java 코드의 일부이다.
    /**
    * Scheduling 서비스를 통해 수행된 Job Object(executeObj)의 수행 결과가 올바른지 알아보는 테스트이다.
    */
    public void testScheduling() throws Exception {
    	Thread.sleep(10000);
    	SchedulingServiceExecute schedulingServiceJob 
    	                        = ( SchedulingServiceExecute )context.getBean("executeObj");
    	
    	int result = schedulingServiceJob.getTestCount();
    	if ( result != 6 ){
    		throw new Exception(" Scheduling Service failed ");
    	}		
    }

Resources