Friday 15 October 2010

Quartz Jobs in Spring 3.0

Elegant Simplicity

The Spring Framework's Quartz integration is a lovely example of a framework doing all the heavy lifting, allowing the developer to concentrate on the actual task.


Thanks to the MethodInvokingJobDetailFactoryBean, any Spring bean can be invoked periodically, with all of Spring's dependency wiring happening exactly as you'd expect. This makes unit testing an absolute breeze - you just test the expected functionality, ignoring the external timing concerns. Even integration testing can be accomplished quickly by substituting a faster schedule; for example, if our "runtime" bean definition looks like this:

<bean name="thingyServiceBean" class="com.millhouse.service.FooService"/>

<bean name="thingyJob" class=
"org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
  <property name="targetObject" ref="thingyServiceBean"/>
  <property name="targetMethod" value="doThingy"/>
  <property name="concurrent" value="false"/>
</bean> 
 
<bean name="thingyTrigger" class=
  "org.springframework.scheduling.quartz.SimpleTriggerBean">
  <property name="jobDetail" ref="thingyJob"/>
  <property name="repeatInterval" value="60000"/> <!-- 60 sec in millis -->
  <property name="repeatCount" value="-1"/> <!-- -1 means forever -->  
</bean>

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
  <property name="triggers">
    <list>
      <ref bean="thingyTrigger"/>
    </list>
  </property>
</bean>
we obviously don't want to have our thingyServiceBean invoked every sixty seconds forever in integration tests, so we supply a different application context for testing:
<import resource="classpath:jobConfig.xml"/>
  
<-- Overridden definition for the trigger: -->
<bean name="thingyTrigger" class=
  "org.springframework.scheduling.quartz.SimpleTriggerBean">
  <property name="jobDetail" ref="thingyJob"/>
  <property name="repeatInterval" value="0"/> 
  <property name="repeatCount" value="1"/> <!-- run once for testing -->  
</bean>
If you're using Maven, placing the "runtime" jobConfig.xml in src/main/resources and the above file in src/test/resources Just Works - and you've proven your Spring wireup is correct. Lovely.

No comments:

Post a Comment

Comments welcome - spam is not. Spam will be detected, deleted and the source IP blocked.