#
# Quartz - http://www.opensymphony.com/quartz/
#
quartz.version=1.5.2
quartz.dir=${lib.dir}/quartz-${quartz.version}
quartz.jar=${quartz.dir}/quartz-all-${quartz.version}.jar
public void checkLastLogin();
public void checkLastLogin() {
log.info("Congratulations! Quartz called the dummy method!");
}
<bean id="dummyJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject"><ref bean="userManager"/></property> <property name="targetMethod"><value>checkLastLogin</value></property> </bean> <bean id="dummyTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> <property name="jobDetail"> <ref bean="dummyJobDetail"/> </property> <property name="startDelay"> <value>30000</value> </property> <property name="repeatInterval"> <value>45000</value> </property> </bean> <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref local="dummyTrigger"/> </list> </property> </bean>The SchedulerFactoryBean serves as a factory for a Quartz scheduler, allowing the registering of scheduled jobs via <list> of <refs> to Trigger beans (either SimpleTriggerBean or CronTriggerBean).
<bean id="dummyCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"/> <property name="jobDetail"/> <ref bean="dummyJobDetail"//> </property/> <property name="cronExpression"/> <!-- Fire every minute starting at 2pm and ending at 2:59pm, every day --/> <value/>0 * 14 * * ?</value/> </property/> </bean/>The CronTriggerBean is very similar to a SimpleTriggerBean, except that a cron expression is required.
public class DummyJob extends QuartzJobBean {
private ApplicationContext ctx;
<!-- Always expose this --/>
public void setApplicationContext(ApplicationContext applicationContext) {
this.ctx = applicationContext;
}
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
SomeManager sm = (SomeManager)ctx.getBean("someManager");
sm.doScheduledOperation();
}
}
As you can see from the code above, it's not possible to inject a bean reference into the QuartzJobBean without incurring serialization issues.
Therefore the service bean has to be retrieved explicitly from the ApplicationContext.
Few additional changes have to be implemented to activate a JDBCJobStore and use a QuartzJobBean:
<pathelement location="${quartz.jar}"/>
The entry has to be added in the "service.compile.classpath" section of the file.
<bean id="dummyJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass">
<value>com.thetapenet.service.DummyJob</value>
</property>
<!-- This would be great, but doesnt work with JDBCJobStore -->
<!--<property name="jobDataAsMap">
<map>
<entry key="someManager">
<ref bean="someManager"/>
</entry>
</map>
</property>-->
</bean>
<bean id="dummyTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
...
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="applicationContextSchedulerContextKey">
<value>applicationContext</value>
</property>
<property name="triggers">
<list>
<ref local="dummyTrigger"/>
</list>
</property>
</bean>
The SchedulerFactoryBean now has two more properties: the "datasource" and the "applicationContextSchedulerContextKey".
"datasource" instructs the SchedulerFactoryBean to activate the JDBCJobStore and use the global datasource defined in the
applicationContext-resources.xml configuration file. The second property is used to propagate the Spring ApplicationContext
all the way to the JobDetailBean. Please note that a JobDetailBean implementation must always expose
public void setApplicationContext(ApplicationContext applicationContext) {
in order for the ApplicationContext to be injected into the Job.