You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Batch注解式无XML:向ItemReader传递JobParameters

Hey there! I get it—working with Spring Batch's Java config can feel a bit tricky when you're used to seeing XML examples, especially when you need to inject dynamic JobParameters into your JdbcCursorItemReader. Let's walk through how to fix this properly.

First, let's understand why your current approach isn't working: your reader() @Bean method runs when the Spring container initializes, but your JobParameters are only available when the Job actually starts executing. That means you can't directly reference them in the bean creation phase. Instead, we need to access the parameters at runtime when the Step is running.

Here are a couple of clean, Java-config-friendly solutions to choose from:

Option 1: Use @StepScope with SpEL (Simplest Approach)

This is the most straightforward method. By marking your reader as @StepScope, Spring will create the bean when the Step executes (instead of at startup), which lets you inject JobParameters directly using Spring Expression Language (SpEL).

@Autowired
private DataSource dataSource;

@Bean
@StepScope // This is the key annotation!
public JdbcCursorItemReader<McsendRequest> reader(
        @Value("#{jobParameters['count']}") Long count) { // Inject the JobParameter directly
    JdbcCursorItemReader<McsendRequest> itemReader = new JdbcCursorItemReader<>();
    itemReader.setDataSource(dataSource);
    // Use the injected count parameter in your SQL
    itemReader.setSql("select xxxx where rownum <= " + count);
    itemReader.setRowMapper(new McsendRequestMapper());
    return itemReader;
}

Just make sure the parameter name (count in this example) matches exactly what you stored in JobParameters via your SendJobParms incrementer. This approach avoids messy listener code and keeps your config clean.

Option 2: Implement StepExecutionAware (For More Control)

If you need more flexibility (like building complex dynamic SQL or accessing multiple JobParameters), you can make your reader implement the StepExecutionAware interface. This lets you grab the StepExecution object (which holds the JobParameters) when the Step starts.

@Bean
public JdbcCursorItemReader<McsendRequest> reader() {
    return new JdbcCursorItemReader<McsendRequest>() {
        private StepExecution stepExecution;

        @Override
        public void setStepExecution(StepExecution stepExecution) {
            this.stepExecution = stepExecution;
            // Now you can access JobParameters here
            JobParameters jobParams = stepExecution.getJobParameters();
            Long count = jobParams.getLong("count");
            
            // Dynamically set your SQL with the parameter
            setSql("select xxxx where rownum <= " + count);
            setDataSource(dataSource);
            setRowMapper(new McsendRequestMapper());
        }
    };
}

Option 3: Use PreparedStatementSetter (Prevent SQL Injection)

If you want to avoid concatenating SQL strings (to prevent injection risks), use a PreparedStatementSetter with placeholders. Combine this with StepExecutionAware to access the parameters at runtime:

@Bean
public JdbcCursorItemReader<McsendRequest> reader() {
    return new JdbcCursorItemReader<McsendRequest>() {
        private StepExecution stepExecution;

        @Override
        public void setStepExecution(StepExecution stepExecution) {
            this.stepExecution = stepExecution;
        }

        @Override
        protected void openCursor(Connection con) throws SQLException {
            // Set up the prepared statement with your parameter
            setPreparedStatementSetter(ps -> {
                JobParameters jobParams = stepExecution.getJobParameters();
                ps.setLong(1, jobParams.getLong("count"));
            });
            setSql("select xxxx where rownum <= ?"); // Use a placeholder for safety
            setDataSource(dataSource);
            setRowMapper(new McsendRequestMapper());
            super.openCursor(con);
        }
    };
}

Quick Notes

  • Double-check that your SendJobParms incrementer is correctly adding the count parameter (or whatever name you're using) to JobParameters.
  • Spring Batch 3.0.8.RELEASE is a bit outdated—if possible, consider upgrading to a newer version for better support and features, but all the above methods work with your current version.

Hope this helps you get your dynamic SQL up and running smoothly!

内容的提问来源于stack exchange,提问作者CardsFan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:22:49