【问题标题】:How do I get Spring Batch Job ContextId in ItemProcessor or ItemWriter?如何在 ItemProcessor 或 ItemWriter 中获取 Spring Batch Job ContextId?
【发布时间】:2013-01-10 17:20:15
【问题描述】:

我需要将 Job ExecutionId 存储为 Entity 的字段之一。 (我正在使用 JpaItemWriter) 这里的主题之一从 StepExecution 解释,我可以得到 StepContext -> JobExecution。那么如何获取 StepExecution?

(我不需要将任何数据从一个步骤传递到另一个步骤,我只需要 JobExecuionId)

感谢您的帮助, 穆尼尔·艾哈迈德

【问题讨论】:

    标签: spring-batch


    【解决方案1】:

    我建议您使用处理器来更新您的实体的价值。如果您的处理器直接实现ItemProcessor<T>,那么您将不会自动获得StepExecution。要获取StepExecution,请执行以下操作之一; - 实现 StepExecutionListener 并将其设置为来自beforeStep 方法的变量 - 创建一个名为[something](StepExecution execution)的方法并使用@BeforeStep进行注释

    一旦您通过侦听器注入 StepExecution,您就可以获取 jobExecutionId 并将其设置到您的实体中

    public class MyEntityProcessor implements ItemProcessor<MyEntity, MyEntity> {
    
    private long jobExecutionId;
    
    @BeforeStep
    public void beforeStep(StepExecution stepExecution) {
        jobExecutionId = stepExecution.getJobExecutionId();
    }
    
    @Override
    public MyEntity process(MyEntity item) throws Exception {
        //set the values
        item.setJobExecutionId(jobExecutionId);
        //continue
        return item;
    }
    
    }
    

    【讨论】:

    • 与你的名字相反的是“完整代码”;-)。感谢您的回答。很好的帮助。
    • 您能否发布用于连接此 bean 的 spring 上下文 xml。我遵循相同的模式,但似乎没有调用 beforeStep()。您是否需要在某处显式地将 MyEntityProcessor bean 注册为侦听器?
    • 我使用了这个解决方案来解决这个问题并且它有效,但事实证明它不是线程安全的。如果您运行多个作业,他们可能会得到错误的作业 ID,这是一个严重的问题。
    • 你必须将此处理器设置为监听器......所以对我来说这个解决方案闻起来不太好......最好将它设置在另一个专门用于此目的的类中
    【解决方案2】:

    我们可以使用 Itemprocessor 的 @Scope("job") 将作用域设置为作业,并且可以使用 @Value("#{jobExecution}") 表达式轻松获取 JobExecution,如下所示。

    @Service
    @Scope("job")
    public class XsltTransformer implements ItemProcessor<Record, Record> {
    
    @Value("#{jobExecution}")
    private JobExecution jobExecution;
    
    }
    

    【讨论】:

    • 我遇到了这个问题,因为项目处理器的范围是“步骤”。相反,我检索了 stepExecution 并通过调用 stepExecution.getJobExecution() 来执行作业。
    【解决方案3】:

    使用@Scope("job") 将范围作为作业,并使用@Value("#{jobExecution}") 获取JobExecution

    【讨论】:

      【解决方案4】:

      您必须添加以下内容:

      @Value("#{stepExecution.jobExecution}")
      
      private JobExecution jobExecution;
      

      在您的阅读器 Writer 或处理器中。 它肯定会起作用。

      【讨论】:

        【解决方案5】:

        如果你想在 MyEntityProcessor 中使用@BeforeStep,你必须像监听器一样声明它

        <batch:listeners>
         <batch:listener ref="myEntityProcessor" />
        </batch:listeners>
        

        【讨论】:

          【解决方案6】:

          当我想获取 JobInstanceID 时,我遇到了类似的问题。下面是我如何获得 StepExecution 然后检索 JobExecution。我希望这会有所帮助。

          public class FoobarItemProcessor implements ItemProcessor<Foobar, Foobar> {
          
          private JobExecution jobExecution;
          
          @BeforeStep
          public void beforeStep(StepExecution stepExecution) {
              jobExecution = stepExecution.getJobExecution();
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-07-29
            • 2023-02-10
            • 1970-01-01
            • 1970-01-01
            • 2021-07-15
            • 2017-08-31
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多