Developer tips

Making Spring and Quartz Work Together Smoothly

Spring has quartz support. But as you can see it requires a lot of old-style xml mappings for each of the jobs you want to run. And it looks more complex than needed. To an extent that it is a common opinion that if you have to use quartz and spring, you should use quartz separately (and not utilize the spring quartz support).

On the other hand spring scheduling has become pretty nice: @Scheduled + task:annotation-driven is what you need for most scenarios. But it is not as feature-rich as quartz – you don’t have an interface for controlling the jobs execution – stop, pause, resume. So quartz can be considered superior. So what do we have as requirements:

use quartz, as a feature-rich scheduling technology

use spring to provide dependency-injection in quartz jobs

make it as simple as possible to write and configure a new job

It appears that you can’t do this. So I had to create something new, on top of existing spring classes, that would make it easier to work with quartz and still have every job instance as spring bean – with dependency injection, AOP, etc. My goals:

Schedule the job with annotation – I started with @Scheduled, but it is based on the idea of annotating methods, rather than classes. And it doesn’t support the richer quartz meta-data (job name, group, durability, etc)

Minimum xml – the whole setup should be enabled through one or two bean definitions, but adding new jobs should not require changes

Ability to control the quartz jobs

I asked a question on stackoverflow, to check if there’s an existing solution. It appears there isn’t, so I implemented the above, and here is the end result (as answer to the stackoverflow question – I won’t copy/paste it here, it looks better there anyway). An example job would look like this:

As you see you don’t even need @Service / @Component, because @ScheduledJob makes use of spring stereotype support (using @Component as meta-annotation). You can also use properties and SpEL in the cronExpression property – you can externalize it, instead of hard-coding it.

There is some room for simplifying it even further. Perhaps I can get rid of the need to implement the Job interface, and instead annotate methods with @ScheduledJob, and then wrapping them in an adapter for the Job interface, but that would make it more complex in the wiring part, without giving that much benefit.

I have already suggested it as improvement to spring. If they like the approach I believe they will fix some issues that I may have overlooked. If they don’t like it, I can make it a separate project.