首页 > 解决方案 > 如何将 List 从 StepExecutionListener 传递到 MultiResourceItemReader

问题描述

在 StepExecutionListener.beforeStep() 执行期间,我正在使用数据库中的数据启动资源列表。

@Component
public class DailyExportStepExecutionListener implements StepExecutionListener {

@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private ResourceLoader resourceLoader;
private List<Resource> listResource;

public DailyExportStepExecutionListener() {
    listResource = new ArrayList<Resource>();
}

public List<Resource> getListResource() {
    return listResource;
}

@Override
public void beforeStep(StepExecution stepExecution) {
    jdbcTemplate.query("SELECT FullPath FROM DailyExportMetadata",
            (rs, row) -> listResource.add(resourceLoader.getResource(rs.getString(1))));
}

最终我想做的是使用 MultiResourceItemReader 的资源列表

@Bean
public MultiResourceItemReader<DailyExport> multiResourceItemReader(FieldSetMapper<DailyExport> testClassRowMapper) {

    MultiResourceItemReader<DailyExport> multiResourceItemReader = new MultiResourceItemReader<>();
    multiResourceItemReader.setName("dailyExportMultiReader");
    multiResourceItemReader.setDelegate(reader(testClassRowMapper));
    multiResourceItemReader.setStrict(true);
    multiResourceItemReader.setResources(??);
    
    return multiResourceItemReader;
}

如何在组件之间传递 ArrayList?

谢谢

标签: springspring-bootspring-batch

解决方案


命名方法的目的multiResourceItemReader是构建将在作业中使用的项目阅读器,因此它在作业开始之前执行,因此在执行之前beforeStep执行。

如果可以,您应该在配置时执行 sql 以填充 listResource:例如在方法注释@Bean方法中:

@Bean
public List<Resource> listResource(JdbcTemplate jdbcTemplate, ResourceLoader resourceLoader) {
    List<Resource> listResource;
    jdbcTemplate.query("SELECT FullPath FROM DailyExportMetadata",
            (rs, row) -> listResource.add(resourceLoader.getResource(rs.getString(1))));
    return listResource;
}

而 multiResourceItemReader 方法就像:

@Bean
public MultiResourceItemReader<DailyExport> multiResourceItemReader(FieldSetMapper<DailyExport> testClassRowMapper, List<Resource> listResource) {

    MultiResourceItemReader<DailyExport> multiResourceItemReader = new MultiResourceItemReader<>();
    multiResourceItemReader.setName("dailyExportMultiReader");
    multiResourceItemReader.setDelegate(reader(testClassRowMapper));
    multiResourceItemReader.setStrict(true);
    multiResourceItemReader.setResources(listResource);
    
    return multiResourceItemReader;
}

如果您无法在开始作业之前初始化 listResource,您应该按照本文中的说明进行操作(从 ExecutionContext 设置 IteamReader 输入)。beforeStep 方法应该像这样将 listResource 放入 step 执行上下文中:

stepExecution.getExecutionContext().put("listResource", listResource);

"listResource"是multiResourceItemReader方法中@Value语句中用来获取列表的key


推荐阅读