I\'m setting up a scheduled tasks scheme in spring, using the task namespace.
I want to schedule most tasks to fire according to a cron expression, and some to fire
If you don't need an initial delay, you can make it run 'just once' on startup as follows:
<task:scheduled-tasks>
<!-- Long.MAX_VALUE ms = 3E8 years; will run on startup
and not run again for 3E8 years -->
<task:scheduled ref="myThing" method="doStuff"
fixed-rate="#{ T(java.lang.Long).MAX_VALUE }" />
</task:scheduled-tasks>
(Of course, if you think your code is going to run for longer than 3E8 years, you may need a different approach...)
If you need an initial delay, you can configure it as follows (I'm testing with Spring 3.1.1) - this doesn't require any additional dependencies and you don't have to write your own trigger, but you do have to configure the PeriodicTrigger
provided by Spring:
<bean id="onstart" class="org.springframework.scheduling.support.PeriodicTrigger" >
<!-- Long.MAX_VALUE ms = 3E8 years; will run 5s after startup and
not run again for 3E8 years -->
<constructor-arg name="period" value="#{ T(java.lang.Long).MAX_VALUE }" />
<property name="initialDelay" value="5000" />
</bean>
<task:scheduled-tasks>
<task:scheduled ref="myThing" method="doStuff" trigger="onstart" />
</task:scheduled-tasks>
Spring 3.2 appears to support the "initial-delay" attribute directly, but I haven't tested this; I'd guess this works:
<task:scheduled-tasks>
<task:scheduled ref="myThing" method="doStuff"
fixed-rate="#{ T(java.lang.Long).MAX_VALUE }"
initial-delay="5000"/>
</task:scheduled-tasks>
If you have a look at the Task namespace XSD, you'll see that there are only three different configuration types: fixed-delay
, fixed-rate
and cron
.
And if you look at the source of ScheduledTasksBeanDefinitionParser, you'll see that no more than one of these values are evaluated. Here is the relevant part:
String cronAttribute = taskElement.getAttribute("cron");
if (StringUtils.hasText(cronAttribute)) {
cronTaskMap.put(runnableBeanRef, cronAttribute);
}
else {
String fixedDelayAttribute = taskElement.getAttribute("fixed-delay");
if (StringUtils.hasText(fixedDelayAttribute)) {
fixedDelayTaskMap.put(runnableBeanRef, fixedDelayAttribute);
}
else {
String fixedRateAttribute = taskElement.getAttribute("fixed-rate");
if (!StringUtils.hasText(fixedRateAttribute)) {
parserContext.getReaderContext().error(
"One of 'cron', 'fixed-delay', or 'fixed-rate' is required",
taskElement);
// Continue with the possible next task element
continue;
}
fixedRateTaskMap.put(runnableBeanRef, fixedRateAttribute);
}
}
So there is no way to combine these attributes. In short: the namespace won't get you there.
My working example:
<bean id="whateverTriggerAtStartupTime" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="whateverJob"/>
<property name="repeatCount" value="0"/>
<property name="repeatInterval" value="10"/>
</bean>
This works and is way easier than the other answers.
// Will fire the trigger 1 + repeatCount number of times, start delay is in milliseconds
simple name: 'mySimpleTrigger', startDelay: 5000, repeatCount: 0