spring批量选择条目读取器数据提供者

z9ju0rcb  于 2021-07-23  发布在  Java
关注(0)|答案(1)|浏览(278)

我有一个基于http请求执行的spring批处理作业。
第一步基于类路径中的某个静态文件(包含工具列表)在本地生成请求文件。
第二步将文件上载到服务器。

@Configuration
@EnableBatchProcessing
public class BatchConfiguration {

    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;

    public BatchConfiguration(final JobBuilderFactory jobBuilderFactory, final StepBuilderFactory stepBuilderFactory) {
        this.jobBuilderFactory = jobBuilderFactory;
        this.stepBuilderFactory = stepBuilderFactory;
    }

    @Bean
    public Job generateRequest(final Step generateRequestStep, final Step uploadRequestStep) {
        return this.jobBuilderFactory.get("MyRequestJob")
                .start(generateRequestStep)
                .next(uploadRequestStep)
                .build();
    }

    @Bean
    public Step generateRequestStep(@Qualifier("instrumentFlatFileItemReader") final ItemReader<Instrument> instrumentItemReader,
                                    @Qualifier("") ItemWriter<Instrument> instrumentItemWriter) {
        return stepBuilderFactory.get("requestStep")
                .chunk(5)
                .reader(instrumentItemReader)
                .writer(instrumentItemWriter)
                .build();
    }

    @Bean
    @Scope(value = "step", proxyMode = ScopedProxyMode.INTERFACES)
    public FlatFileItemReader<Instrument> instrumentFlatFileItemReader(@Value("#{jobExecutionContext['feedType']}") String feedType) {
        FlatFileItemReader<Instrument> reader = new FlatFileItemReader<>();
        reader.setResource(new ClassPathResource("/path/to/static/file", getClass().getClassLoader()));

        DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
        tokenizer.setNames("column1", "column2");
        tokenizer.setStrict(false);

        DefaultLineMapper<Instrument> lineMapper = new DefaultLineMapper<>();
        lineMapper.setLineTokenizer(tokenizer);
        lineMapper.setFieldSetMapper(new InstrumentFieldMapper());
        lineMapper.afterPropertiesSet();

        reader.setLineMapper(lineMapper);

        return reader;
    }

    @Bean
    @StepScope
    public ItemStreamWriter<Instrument> instrumentItemStreamWriter(@Value("#{jobExecutionContext['FILE_OUTPUT_PATH']}") String requestFilePath) {
        BeanWrapperFieldExtractor<Instrument> fieldExtractor = new BeanWrapperFieldExtractor<>();

        DelimitedLineAggregator<Instrument> lineAggregator = new DelimitedLineAggregator<>();
        lineAggregator.setFieldExtractor(fieldExtractor);

        return new FlatFileItemWriterBuilder<Instrument>()
                .name("instrumentWriter")
                .resource(new FileSystemResource(requestFilePath))
                .delimited()
                .fieldExtractor(fieldExtractor)
                .lineAggregator(lineAggregator)
                .shouldDeleteIfExists(true)
                .build();

    }
}

目前,只有一种方法可以从静态文件加载仪器。我现在有一些需求,用户可以指定从哪个媒体加载静态数据,例如本地类路径、数据库或从调用webservice。
我不确定要遵循什么样的模式来设计这个。目前,我正在使用平面文件项目阅读器,但这将不适用于数据库,外部服务。我需要一些帮助来将此放在接口后面,并能够根据所选的媒体类型导出相应的接口:
例如:http请求可以提供要使用的媒体类型:

{
  jobName: "REQUEST",
  cobDate: "2021-02-22",
  type: EOD,
  media: "DATABASE"
} //load list from database table

{
  jobName: "REQUEST",
  cobDate: "2021-02-22",
  type: EOD,
  media: "FILE_SYSTEM"
}  //load list from static file
pxiryf3j

pxiryf3j1#

我把媒体放进了jobparameter
在这种情况下,您可以创建一个步骤范围的bean,并基于该作业参数返回所需的项读取器实现:

@Bean
@StepScope
public ItemStreamReader<Instrument> instrumentFlatFileItemReader(@Value("#{jobParameters['mediaType']}") String mediaType) {
   ItemStreamReader<Instrument> reader;     
   // TODO create FlatFileItemReader or JdbcCursorItemReader based on mediaType
   return reader;
}

相关问题