![](/img/trans.png)
[英]Partitioner implements StepExecutionListener but beforeStep is not called
[英]How to skip a step execution from beforeStep method in StepExecutionListener?
我想为任何步骤实现一个通用的 StepExecutionListener 所以在 beforeStep 方法中(也就是说,在当前步骤 tasklet 开始之前)它可以检查一些与数据库相关的条件:如果不成功,它将跳过当前步骤并继续与下一个。
在下面:
public void beforeStep(StepExecution stepExecution)
目前我在“stepExecution”object 中没有找到任何东西可以做到这一点。 我只是将退出状态更改为 COMPLETED,但仍然执行相应的 tasklet。
有没有办法做到这一点? 我也听说过决策者,但我不喜欢在我的 XML 上添加太多冗长的配置。
提前致谢。
在这种情况下,决策者是更好的选择,因为它们的唯一目的是决定是否执行您的步骤。 他们确实使 xml 变得冗长,但这更好,因为其他人一眼就能理解。
我认为 beforeStep 可以处理此问题的唯一方法是,如果您在任务名称属于您要忽略的名称时抛出异常。 但是,即使上一步失败,您的下一步也可能需要配置为运行(如果未跳过该步骤时这不是您想要的,则不推荐)。
但是,如果你的任务扩展,你需要决定 3-4 个步骤,在 beforeStep 中处理会变得很麻烦。
让我知道你用什么 go !
编辑:
决策者的使用示例以及步骤
<batch:decision id="decider1" decider="deciderClass1">
<batch:next on="FAILED" to="decider2" />
<batch:next on="COMPLETED" to="task1"/>
</batch:decision>
<batch:step id="step1" next="decider2" parent="step1Class"/>
<batch:decision id="decider2" decider="deciderClass2">
<batch:next on="FAILED" to="step3" />
<batch:next on="COMPLETED" to="step2"/>
</batch:decision>
<batch:step id="step2" parent="step2Class" next="step3"/>
.....
我会回答自己以介绍一些代码。
根据 Priteesh 的提议,我定义了一个这样的决策者:
<decision id="deciderId" decider="deciderDeclaration">
<next on="CONTINUE" to="step1" />
<next on="SKIP" to="finalStep" />
</decision>
在我的上下文中将它放在首位。xml。 这很重要,因为如果不满足条件,step1 永远不会执行。
我的决定是这样的:
public class StepExecutionDecider implements JobExecutionDecider{
/** LOGGER. */
private Logger LOGGER = ...
private static final String FLOW_STATUS_CONTINUE = "CONTINUE";
private static final String FLOW_STATUS_SKIP = "SKIP";
@Override
public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {
String status = FLOW_STATUS_CONTINUE;
String condition = ....
if (Constants.NO.equals(condition)){
LOGGER.warn(jobExecution.getJobInstance().getJobName(), " -> The Step execution is disabled. Continuing with the next Step.");
status = FLOW_STATUS_SKIP;
}
return new FlowExecutionStatus(status);
}
...
}
奇怪的是,每当我的条件不满足时,LOGGER 消息就会在我的日志中打印两次,时间戳完全相同......
无论如何,非常感谢 Priteesh 的帮助。
我有相同的目标:在StepExecutionListener
中使用beforeStep()
来检查非 Spring 批处理相关条件,以确定该步骤是否应该运行。
使用决策程序 ( JobExecutionDecider
) 不起作用,因为JobExecutionDecider.decide()
接收先前执行的步骤作为参数。 决策者的目的是让您检查上一步执行的状态以选择下一步做什么。 如果我正在测试特定于StepXYZ的条件,我需要在执行该步骤之前执行该步骤。
好吧, StepExecutionListener.execute()
在执行之前将StepXyz执行放在您的手上。 听起来很有希望......但是, API 没有任何机制告诉 spring 批处理不要运行StepXyz 。 为了说明这一点,下面的任何陈述都不会做我们想要的。
stepExecution.status = BatchStatus.ABANDONED
stepExecution.exitStatus = ExitStatus.NOOP
stepExecution.setTerminateOnly()
在搜索了所有框架代码、SO 和 spring 文档之后,我的结论是:
不能使用
beforeStep()
优雅地告诉 spring 批处理不要运行该步骤。
(我正在使用 Spring 引导 2.3.9。)
在我的情况下,要测试的条件是一个或多个功能标志。 我已经有一个 FeatureFlags Component
,所以我将它注入到 tasklet 中,并在execute()
开始时测试了前置条件:
override fun execute(contribution: StepContribution, chunkContext: ChunkContext): RepeatStatus? {
if (!featureFlags.stepShouldRun) {
contribution.exitStatus = ExitStatus("SKIPPED BASED ON FEATURE FLAGS")
return RepeatStatus.FINISHED
}
return execute()
}
fun execute(): RepeatStatus {
// the actual step logic goes here
// add StepContribution as a param if necessary
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.