views:

1706

answers:

5

In my application there is a requirement to be able to create Scheduled Job(s) depending on the type of Request that comes in (Dynamically).

Can I still use Spring to create and trigger Jobs? If Yes, how?

Any help would be useful.

+3  A: 

Look at CronTriggerBean and JobDetailBean. The 'MyJob' class mocked up below is an instance of QuartzJobBean. The cron expression is what you'd expect, but with seconds as its first value.

<beans>
   <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
      <property name="startupDelay" value="5"/>
      <property name="waitForJobsToCompleteOnShutdown" value="false"/>
      <property name="triggers">
         <list>
            <bean class="org.springframework.scheduling.quartz.CronTriggerBean">
               <property name="jobDetail">
                  <bean class="org.springframework.scheduling.quartz.JobDetailBean">
                     <property name="jobClass" value="edu.vt.MyJob"/>
                     <property name="jobDataAsMap">
                        <map>
                           <entry key="messageSource" value-ref="messageSource"/>
                           <entry>
                              <key><value>anotherProperty</value></key>
                              <bean class="edu.vt.MyUsefulBean">
                                 <constructor-arg index="0" value="..."/>
                              </bean>
                           </entry>
                        </map>
                     </property>
                  </bean>
               </property>
               <property name="cronExpression" value="0 * * * * ?"/>
            </bean>
         </list>
      </property>
   </bean>
</beans>
Joe Liversedge
+1  A: 

You can also get Spring to trigger methods on your beans using Quartz (i.e. youdon't need to create any Quartz-specific classes at all) using the MethodInvokingJobDetailFactoryBean in the package org.springframework.scheduling.quartz

oxbow_lakes
+1  A: 

Given that the SchedulerFactoryBean exposes a native Quartz Scheduler object, you can wire that directly into your controller class, and then dynamically create and register triggers and jobs with the Scheduler object.

Spring itself can't be used for the scheduling of the dynamically created jobs, since Spring's bean support will be used for statically configured jobs, but the native Quartz Scheduler API is reasonable enough to use on its own (barely). As fr triggering of the jobs, that Quartz's job, not Spring's.

edit: either I'm mis-understanding the original question, or everyone else is. The other answers all detail how to statically wire up a series of quartz jobs using Spring, but the question was how to dynamically schedule jobs as requests come in.

skaffman
A: 

You can download sample source code from this link

<?xml version="1.0" encoding="UTF-8"?>

<!--  scheduler factory -->
<bean id="com.notary.app.invoicing.scheduler.SchedulerFactory" 
  class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
        <list>
            <ref bean="ASFImportTrigger"/>
        </list>
    </property>
 <property name="dataSource">
  <ref bean="datasource"/>
 </property>
 <property name="transactionManager">
  <ref bean="transactionManager"/>
 </property>
    <property name="quartzProperties">
  <props>
   <prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
   <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.MSSQLDelegate</prop>
   <prop key="org.quartz.jobStore.misfireThreshold">60000</prop>
   <prop key="org.quartz.jobStore.selectWithLockSQL">SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?</prop>
   <prop key="org.quartz.plugin.triggHistory.class">org.quartz.plugins.history.LoggingTriggerHistoryPlugin</prop>
   <prop key="org.quartz.plugin.triggHistory.triggerFiredMessage">Trigger {1}.{0} fired job {6}.{5} at: {4, date, HH:mm:ss dd/MM/yyyy}</prop>
   <prop key="org.quartz.plugin.triggHistory.triggerCompleteMessage">Trigger {1}.{0} completed firing job {6}.{5} at {4, date, HH:mm:ss dd/MM/yyyy} with resulting trigger instruction code: {9}</prop>
   <prop key="org.quartz.plugin.jobHistory.class">org.quartz.plugins.history.LoggingJobHistoryPlugin</prop>
   <prop key="org.quartz.plugin.jobHistory.jobSuccessMessage">Job {1}.{0} fired at: {2, date, dd/MM/yyyy HH:mm:ss} result=OK</prop>
   <prop key="org.quartz.plugin.jobHistory.jobFailedMessage">Job {1}.{0} fired at: {2, date, dd/MM/yyyy HH:mm:ss} result=ERROR</prop>
  </props>
 </property>
 <property name="overwriteExistingJobs" value="true"/>
 <property name="startupDelay" value="50"/>
 <property name="applicationContextSchedulerContextKey">
  <value>applicationContext</value>
 </property>
</bean>

Firstthumb
A: 

A year later and I find myself having to something very similar. Googling around, I found this link which describes getting access to the application context from within a scheduled job through the JobExecutionContext. I think I will be creating an abstract type job that can do some of the actual job creation and use a prototype to actual inject required services when the job needs to run.

Matt