Java 使用 Spring 任务命名空间安排任务运行一次

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3564361/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 01:53:49  来源:igfitidea点击:

Scheduling tasks to run once, using the Spring task namespace

javaspring

提问by Karl Johansson

I'm setting up a scheduled tasks scheme in spring, using the task namespace.

我在 spring 中设置了一个计划任务方案,使用任务命名空间。

I want to schedule most tasks to fire according to a cron expression, and some to fire just once, a fixed delay after startup, and then never again (i.e. what setting repeatCountto 0on a SimpleTriggerBean would achieve).

我想根据cron表达式大多数的任务安排到火,有的在启动后只启动一次,一个固定的延迟,然后再也没有(即什么设置repeatCount,以0将实现在SimpleTriggerBean)。

Is it possible to achieve this within the task namespace, or do I need to revert to defining beans for my triggers?

是否可以在任务命名空间中实现这一点,或者我是否需要恢复为我的触发器定义 bean?

采纳答案by Sean Patrick Floyd

If you have a look at the Task namespace XSD, you'll see that there are only three different configuration types: fixed-delay, fixed-rateand cron.

如果您查看Task 命名空间 XSD,您将看到只有三种不同的配置类型:fixed-delayfixed-ratecron

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:

如果您查看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);
    }
}

So there is no way to combine these attributes. In short: the namespace won't get you there.

所以没有办法组合这些属性。简而言之:命名空间不会让你到达那里。

回答by aruizca

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>

回答by Jeremy Gehrs

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

回答by bacar

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

(当然,如果您认为您的代码将运行超过3E8 年,您可能需要不同的方法......)

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 PeriodicTriggerprovided by Spring:

如果您需要初始延迟,您可以按如下方式配置(我正在使用 Spring 3.1.1 进行测试) - 这不需要任何额外的依赖项,您不必编写自己的触发器,但您必须配置PeriodicTriggerSpring提供的:

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

Spring 3.2 似乎直接支持“initial-delay”属性,但我还没有测试过;我猜这有效:

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