Wednesday, September 24, 2008

The Mysterious Ways of SchedulerFactoryBean

Using Spring framework and Quartz, I wanted to make some dynamic Jobs and triggers. After banging my head and some accidents I finally understood how to use it. The API docs say:

"For dynamic registration of jobs at runtime, use a bean reference to this SchedulerFactoryBean to get direct access to the Quartz Scheduler (org.quartz.Scheduler). This allows you to create new jobs and triggers, and also to control and monitor the entire Scheduler."

What the hell that means, I couldn't figure. Hunting for some examples on the web didn't help either. In one of my posts I have given a link to fine tune SchedulerFactoryBean for static jobs. Picking from there, let us assume you have a Stocks Alert Manager to which you wish to give a spring managed scheduler using your very own SchedulerFactoryBean . Let us assume your stockAlertsManager looks like this:


Then your bean config should look something like this:

If you have not noticed, the scheduler property of StockAlertsManager is of type org.quartz.impl.StdScheduler but in the bean config I have set it to the reference of our all-powerful SchedulerFactoryBean. Despite of the mismatch in types your spring application will not complain and initialize the scheduler property nicely. Even when SchedulerFactoryBean does not in any way extend StdScheduler or implement Scheduler . Wierd, counter-intuitive but works. Re-visiting the API doc:

"For dynamic registration of jobs at runtime, use a bean reference to this SchedulerFactoryBean to get direct access to the Quartz Scheduler (org.quartz.Scheduler). This allows you to create new jobs and triggers, and also to control and monitor the entire Scheduler."

Well, they literally meant it! Who would have thought?!

7 comments:

ArrayLust said...

Thanks for the tip - just what I was looking for.

Saveen said...

You are welcome Mick. If there is any other problem or something interesting that you find, please feel free to share :)

Unknown said...

Thanks A lot !!! I was asking my self the same question...

Unknown said...

This poses a problem though.
I need the SchedulerFactorybean in another service. But injecting SchedulerfactoryBean into a variable of that type will result in a CastException because Spring transforms the SchedulerFactoryBean into StdScheduler. Anyone has a solution to that>

Unknown said...

I was tackling with what elnbado had, I just couldn't see what was in front of my eyes. You just need to use org.quartz.impl.StdScheduler instead of SchedulerFactoryBean as the type of the property that you injected.
Thanks for the post, it helped a lot.

Wes said...

@elnbado This may be achieved by prepending the bean id with '&' (sans quotes) when calling the getBean method of the BeanFactory.

Wes said...

@elnbado This may be achieved by prepending the bean id with '&' (sans quotes) when calling the getBean method of the BeanFactory.