繁体   English   中英

如何在spring-batch中将参数从ItemReader传递到ItemProcessor?

[英]How to pass parameters from ItemReader to ItemProcessor in spring-batch?

问题很简单:如何将仅在ItemReader知道的值(例如当前文件名)传递给ItemProcessor

@Bean
@JobScope
public ItemReader<String> reader(@Value("#{jobParameters['path]}") String path) {
    FlatFileItemReader<String> delegate = new FlatFileItemReader<>();
    delegate.setLineMapper(new PassThroughLineMapper());

    Resource[] res = new PathMatchingResourcePatternResolver().getResources("file:" + path);

    MultiResourceItemReader<String> r = new MultiResourceItemReader<>();
    r.setResources(res);
    r.setDelegate(delegate);
    return r;
}

@Bean
public ItemProcessor<String, String> processor() {
    return new ItemProcessor<String, String>() {

        @Override
        public String process(String item) throws Exception {
            //TODO I need the filename that is currently processed. HOW?
            return null;
        }
    };
}

为了安全起见,应将文件名添加到阅读器返回的对象中。 为此,您必须实现自己的包装阅读器。 像这样:

public class MyReader {
     private MultiResourceItemReader delegatereader;

     public MyContainerDto read() {
          String line = delegatereader.read();
          if (line==null) return null;

          Resource currentResource = delegatereader.getCurrentResource();

          MyContainerDto container = MyContainerDto();
          container.setLine(line);
          container.setResourceName(currentResource.getFileName());
          return container;
     }

     ...
} 

(此代码未经测试,仅说明了我要采取的方法)

在我的笔记本电脑上,我能够在一秒钟内创建100万个对象,因此创建对象所需的额外性能并不会真正影响整体性能。

问题是,读取器读取的数据量与块大小定义的一样多。 之后,它将为该块中的每个项目调用处理器。 因此,在一个块中,其中的各项可能已从其他文件中读取。 因此,除了在阅读器中将行和文件名绑定在一起,别无其他方法。

另请参阅https://blog.codecentric.de/zh/2012/03/transactions-in-spring-batch-part-1-the-basics/

最好为读者介绍一个dto。

public class ResourceAwareString implements ResourceAware {
     private String content;
     private Resource res;

     @Override
     public void setResource(Resource res) {
         this.res = res;
     }
}

然后, MultiResourceItemReader<ResourceAwareString>将自动检测它并将资源写入dto。

另一种方法是使ItemReaderItemProcessor @StepScope使用@BeforeStep来访问当前的StepExection上下文。 然后可以设置/获取值,从而将值从读取器传输到处理器,甚至传输到写入器。

请注意, @BeforeStep仅适用于公共类, @BeforeStep用于匿名方法,例如:

new FlatFileItemReader<String>() {
  @BeforeStep
  public void before(StepExecution stepEx) {
       //this will never be called! don't do this.
  }
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM