Планирование задач для запуска один раз с использованием пространства имен задач Spring

Я настраиваю схему запланированных задач в spring, используя пространство имен задач.

Я хочу запланировать выполнение большинства задач в соответствии с выражением cron, а некоторые - только один раз, фиксированная задержка после запуска, а затем никогда больше (т.е. какая настройка repeatCount to 0 на SimpleTriggerBean достигла бы).

Можно ли достичь этого в пространстве имен задач или мне нужно вернуться к определению beans для моих триггеров?

Ответ 1

Если вы посмотрите на пространство имен задач XSD, вы увидите, что существует только три разных типа конфигурации: fixed-delay, fixed-rate и cron.

И если вы посмотрите на источник ScheduledTasksBeanDefinitionParser, вы увидите, что оценивается не более одного из этих значений. Вот соответствующая часть:

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);
    }
}

Таким образом, нет возможности объединить эти атрибуты. Короче: пространство имен не приведет вас туда.

Ответ 2

Если вам не нужна начальная задержка, вы можете запустить его только один раз при запуске следующим образом:

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

(Конечно, если вы думаете, что ваш код будет работать дольше 3E8 лет, вам может потребоваться другой подход...)

Если вам нужна начальная задержка, вы можете настроить ее следующим образом (я тестирую с помощью Spring 3.1.1) - это не требует каких-либо дополнительных зависимостей, и вам не нужно писать свой собственный триггер, но вам нужно настроить PeriodicTrigger, предоставленный 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, похоже, напрямую поддерживает атрибут "начальная задержка", но я не тестировал это; Я предполагаю, что это работает:

<task:scheduled-tasks>
    <task:scheduled ref="myThing" method="doStuff" 
                        fixed-rate="#{ T(java.lang.Long).MAX_VALUE }" 
                        initial-delay="5000"/>
</task:scheduled-tasks>

Ответ 3

Мой рабочий пример:

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

Ответ 4

Это работает и намного проще, чем другие ответы.

    // Will fire the trigger 1 + repeatCount number of times, start delay is in milliseconds
    simple name: 'mySimpleTrigger', startDelay: 5000, repeatCount: 0