自定义ListItemReader春季批次

发布于 2025-02-13 12:45:06 字数 1440 浏览 0 评论 0 原文

我对 listItemreader 的自定义实现进行了编码,并在Spring Batch的GitHub中遵循该示例。无论如何,就我而言,我需要从 JobContext 中读取一个变量,此变量是我必须读取包含文件的途径。我无法使用构造函数,因为构造函数在 beforestep 事件之前执行,并且目前我没有这些。

无论如何,这将首先执行,但是如果列表再也不会转到null,我将无法再次执行 initialize 方法。

如果我尝试在!list.isempty()条件中添加另一个,将我的列表设置为null。我进入无限循环。

还有其他方法可以解决这个问题吗?也许我过度复杂化了。

public class ListItemReader<Path> implements ItemReader<Path>, StepExecutionListener {

    private List<Path> list;
    private org.springframework.batch.core.JobExecution jobExecution;

    public ListItemReader() {
        this.list = new ArrayList<>();
    }

    public void initialize(){

        //Here I made an listdirectories of a path and add all the files to the list
        String pathString = jobExecution.getExecutionContext().getString(Constants.CONTEXT_PATH);
        Path path = Paths.get(pathString );
        ...
        items.add(Paths.get(..path..));
    }

    @Nullable
    @Override
    public T read() {
        if(list == null) initialize();

        if (!list.isEmpty()) {
            return list.remove(0);
        }
        return null;
    }

    @Override
    public ExitStatus afterStep(StepExecution se) {
        return ExitStatus.COMPLETED;
    }

    @Override
    public void beforeStep(StepExecution se) {
        jobExecution = se.getJobExecution();
    }
}

I coded a custom implementation of ListItemReader, triying to follow the example in the spring batch's github. Anyway, in my case, I need read a variable from the jobContext, this variable is a path where I have to read the files that contains. I can't use the constructor because the constructors executes before the beforeStep event and I don't have these var at this moment.

Anyway this will work first execution, but if the list never goes again to null I can't execute again the initialize method.

If I tried add an else in the !list.isEmpty() condition that set my list to null. I enter in an infinite loop.

There are other methods to solve this? Maybe I am overcomplicating this.

public class ListItemReader<Path> implements ItemReader<Path>, StepExecutionListener {

    private List<Path> list;
    private org.springframework.batch.core.JobExecution jobExecution;

    public ListItemReader() {
        this.list = new ArrayList<>();
    }

    public void initialize(){

        //Here I made an listdirectories of a path and add all the files to the list
        String pathString = jobExecution.getExecutionContext().getString(Constants.CONTEXT_PATH);
        Path path = Paths.get(pathString );
        ...
        items.add(Paths.get(..path..));
    }

    @Nullable
    @Override
    public T read() {
        if(list == null) initialize();

        if (!list.isEmpty()) {
            return list.remove(0);
        }
        return null;
    }

    @Override
    public ExitStatus afterStep(StepExecution se) {
        return ExitStatus.COMPLETED;
    }

    @Override
    public void beforeStep(StepExecution se) {
        jobExecution = se.getJobExecution();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

玩物 2025-02-20 12:45:06

我无法使用构造函数,因为构造函数在beforestep事件之前执行,而我目前没有这些。

实际上,您可以使用 @jobscope @stepscope 延迟bean构造函数。此外,您可以使用 @Value 和Spring Spel 注入您的 JobParameters

在您的情况下,您可能需要重写代码,例如:

@Configuration
@RequiredArgsConstructor
public class YourJobConfig {
  private final StepBuilderFactory stepBuilder;

  @Bean("yourStep")
  public Step doWhatever() {
    return stepBuilder
      .get("yourStepName")
      .<Path, Path>chunk(50) // <-- replace your chunk size here
      .reader(yourItemReader(null, 0)) // <-- place your default values here
      .process(yourItemProcessor())
      .writer(yourItemWriter())
  }

  @Bean
  public ItemReader<Path> yourItemReader(
    @Value("#{jobParameters['attribute1']}") String attribute1,
    @Value("#{jobParameters['attribute2']}") long attribute2    
  ) {
    return new ListItemReader(attribute1, attribute2) // <-- this is your ListItemReader
  }

  @Bean
  public ItemProcessor<Path, Path> yourItemProcessor(){
    return new YourItemProcessor<>();
  }

  @Bean
  public ItemWriter<Path> yourItemWriter(){
    return new YourItemWriter<>();
  }
}

开始工作之前,您可以添加一些 JobParameters

public JobParameters getJobParams() {
  JobParametersBuilder params = new JobParametersBuilder();

  params.addString("attribute1", "something_cool");
  params.addLong("attribute2", 123456);

  return params.toJobParameters();
}

并将其添加到您的工作中:

Job yourJob = getYourJob();
jobParameters jobParams = getJobParams();
JobExecution execution = jobLauncher.run(job, jobParams);

参考

I can't use the constructor because the constructors executes before the beforeStep event and I don't have these var at this moment.

Actually, you can delay your bean constructor by using @JobScope and @StepScope. Additionally, you can use @Value and Spring SpEL to inject your jobParameters.

In your case, you might want to rewrite your code, for e.g:

@Configuration
@RequiredArgsConstructor
public class YourJobConfig {
  private final StepBuilderFactory stepBuilder;

  @Bean("yourStep")
  public Step doWhatever() {
    return stepBuilder
      .get("yourStepName")
      .<Path, Path>chunk(50) // <-- replace your chunk size here
      .reader(yourItemReader(null, 0)) // <-- place your default values here
      .process(yourItemProcessor())
      .writer(yourItemWriter())
  }

  @Bean
  public ItemReader<Path> yourItemReader(
    @Value("#{jobParameters['attribute1']}") String attribute1,
    @Value("#{jobParameters['attribute2']}") long attribute2    
  ) {
    return new ListItemReader(attribute1, attribute2) // <-- this is your ListItemReader
  }

  @Bean
  public ItemProcessor<Path, Path> yourItemProcessor(){
    return new YourItemProcessor<>();
  }

  @Bean
  public ItemWriter<Path> yourItemWriter(){
    return new YourItemWriter<>();
  }
}

Before starting your job, you can add some jobParameters:

public JobParameters getJobParams() {
  JobParametersBuilder params = new JobParametersBuilder();

  params.addString("attribute1", "something_cool");
  params.addLong("attribute2", 123456);

  return params.toJobParameters();
}

and add it to your job:

Job yourJob = getYourJob();
jobParameters jobParams = getJobParams();
JobExecution execution = jobLauncher.run(job, jobParams);

References

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文