如何将字符串(非托管bean)传递到托管bean

时间:2018-12-24 05:41:27

标签: spring spring-batch spring-ioc

我有一个春季批处理工作。有一个步骤正在调用reader方法。

STEP

@Bean public Step myStep(FlatFileItemWriter<String> writer, Processor
processor,  @Value("${com.tableName}") String myTableName) {
    return stepBuilderFactory.get("step1")
        .<MyBean, String> chunk(this.chuckSize)
        .reader(reader(myTableName, this.myRowMapper))
        .processor(processor)
        .writer(writer)
        .build(); 
}

阅读器 工作

@Bean
public <T> JdbcCursorItemReader<T> reader(@Value("${com.tableName}") String tableName, RowMapper<T> rowMapper) {
    JdbcCursorItemReader<T> jdbcCursorItemReader = new JdbcCursorItemReader<>();
    String query = "select * from " + tableName;
    jdbcCursorItemReader.setDataSource(dataSource);
    jdbcCursorItemReader.setSql(query);
    jdbcCursorItemReader.setRowMapper(rowMapper);

    return jdbcCursorItemReader;
}

我希望我的读者使用动态表格名。因此,我将读者更改为如下所述。

@Bean
public <T> JdbcCursorItemReader<T> reader(String tableName, RowMapper<T> rowMapper) {
    JdbcCursorItemReader<T> jdbcCursorItemReader = new JdbcCursorItemReader<>();
    String query = "select * from " + tableName;
    jdbcCursorItemReader.setDataSource(dataSource);
    jdbcCursorItemReader.setSql(query);
    jdbcCursorItemReader.setRowMapper(rowMapper);

    return jdbcCursorItemReader;
}

这会导致以下错误。

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of method reader in com.walgreens.oracleextractionbatch.OracleExtractionJobConfiguration required a bean of type 'java.lang.String' that could not be found.


Action:

Consider defining a bean of type 'java.lang.String' in your configuration.

在激烈的谷歌搜索后,我尝试了许多变通方法。但是我想我缺少一些基本的东西。请帮忙。 TIA

2 个答案:

答案 0 :(得分:0)

在Spring批处理环境中使Reader动态化会使他们变得懒惰。

我们可以使用@StepScope使读者和作家变得懒惰。现在,借助StepScope,我们可以传递参数。传递参数的最流行方法是使用JobParametersstepExecutionContext

在您的情况下,如果您知道作业开始时的表名,请使用JobParameters

在步骤中访问JobParameters的示例代码。

 @Bean
        @StepScope
        public <T> JdbcCursorItemReader<T> reader(@Value("#{jobParameters['tableName']}") String tableName), RowMapper<T> rowMapper) {

如果要通过某些处理(在上一步中)获得表名,那么您需要在stepExecutionContext中设置表名

这是您可以从stepExecutionContext访问表名的方法

 @Bean
    @StepScope
    public <T> JdbcCursorItemReader<T> reader(@Value("#{stepExecutionContext['tableName']}") String tableName), RowMapper<T> rowMapper) {
        JdbcCursorItemReader<T> jdbcCursorItemReader = new JdbcCursorItemReader<>();
        String query = "select * from " + tableName;
        jdbcCursorItemReader.setDataSource(dataSource);
        jdbcCursorItemReader.setSql(query);
        jdbcCursorItemReader.setRowMapper(rowMapper);

        return jdbcCursorItemReader;
    }   

我希望这对您有帮助

答案 1 :(得分:0)

我将 Reader Writer Step bean的范围更改为 prototype 。我将处理器bean的范围保留为(Singleton),因为所有情况下的处理器逻辑都是相同的。

感谢,阿卡什