Using Quartz with Spring


Using Quartz with Spring



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.




Intent of Spring form command

1:



Can a Spring form command be a Map?
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: No transaction manager has been configured
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).


Acquiring a spring configuration value from a custom class
As fr triggering of the jobs, that Quartz's job, not Spring's..
How do you make a multi-module spring configuration?
edit: either I'm mis-understanding the original question, or everyone else is.


How to XML configure Spring bean for constructor injection when bean has varargs constructor
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.


What are the benefits of dependency injection containers?
.
What design patterns are used in Spring framework? [closed]


2:


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> 


3:


There does not seem to be much complete information on this.

This is how I schedule jobs dynamically.

Of course you could replace the simple trigger with some other trigger.. Spring beans:.
<bean name="dailyUpdateJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">     <property name="jobClass" value="com.somecompany.scheduler.DailyUpdates" /> </bean>  <bean id="dailyCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">     <property name="jobDetail" ref="dailyUpdateJob" />     <!-- run every morning at 4:15 AM -->     <property name="cronExpression" value="00 15 04 * * ?" />    </bean>  <bean name="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">     <property name="triggers">         <list>             <ref bean="dailyCronTrigger" />             <ref bean="weeklyReportsCronTrigger" />         </list>     </property>     <property name="applicationContextSchedulerContextKey">         <value>applicationContext</value>     </property> </bean>      
To run the job immediately get a reference to the scheduler and the job, attach a simple trigger and put it into the scheduler, like this:.
    @Autowired     SchedulerFactoryBean scheduler;      @Autowired      @Qualifier("dailyUpdateJob")     JobDetailFactoryBean dailyJob;      public void dynamicJobTrigger() throws Exception {         // Create a trigger for "now"          SimpleTrigger trigger = (SimpleTrigger) newTrigger()                     .startAt(new Date())                     .forJob(dailyJob.getObject())                     .build();          // And drop it into the scheduler for immediate execution         scheduler.getScheduler().scheduleJob(trigger);     }    


4:


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> 
.


5:


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.


6:


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..


7:


Spring 3 (latest version at time of writing) supports setting up jobs almost completely with annotations.. See: Spring reference on scheduling.



74 out of 100 based on 84 user ratings 734 reviews