简体   繁体   中英

How can I configure Spring Batch StepScope using java-based configuration?

I'm setting up a job server using Spring Batch. My JdbcCursorItemReader needs to be configured with sql that changes on a per-job run basis. Because the sql changes, I want the reader to have @StepScope so I don't need to worry about sql statefulness.

So I've setup a class like this:

public class ParameterSettingJdbcCursorItemReader extends JdbcCursorItemReader implements StepExecutionListener {

    @Override
    public void beforeStep(StepExecution stepExecution) {

        JobParameters jobParameters = stepExecution.getJobParameters();

        if (jobParameters != null) {
            List<Object> args = new ArrayList<Object>();
            for (JobParameter jobParameter : jobParameters.getParameters().values()) {
                args.add(jobParameter.getValue());
            }

            Object[] arrayArgs = args.toArray(new Object[args.size()]);
            String sql = String.format(getSql(), arrayArgs);
            setSql(sql);
        }
    }

    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {
        return null;
    }
}

The idea is that I pass sql parameters to the object via JobParameters and use String.format to fill in the dynamically-changing sql.

I am using Java-based configuration throughout my server. My bean for one instance of my ItemReader looks like:

@Bean
@StepScope
public ItemReader<MyInputObject> myInputObjectItemReader() {
    ParameterSettingJdbcCursorItemReader itemReader = new ParameterSettingJdbcCursorItemReader();
    itemReader.setDataSource(myDataSource());
    itemReader.setSql("SELECT * FROM my_table WHERE date = '%1$s'");
    itemReader.setRowMapper(myInputObjectMapper);
    return itemReader;
}

When I start up my server and run the Spring Batch job, I get this error: java.lang.IllegalStateException: No Scope registered for scope 'step'

I've read elsewhere that in order to be able to use StepScope, one needs to first add it to the xml app configuration like this : <bean class="org.springframework.batch.core.scope.StepScope" />

But since I'm using Java-based configuration, that's not an option.

So how do I register the StepScope via a Java-based config? I've tried this:

@Bean
public org.springframework.batch.core.scope.StepScope stepScope() {
    return new org.springframework.batch.core.scope.StepScope();
}

... but when I do I get all sorts of NPEs during app startup on beans that have no relation to StepScope.

Thanks in advance.

You have to register the scope with the ApplicationContext . Normally that would be done for you when you use @EnableBatchProcessing . Did you do that (add that annotation to one of your @Configurations )?

+1 to Dave's point about using @EanbleBatchProcesssing. That will add a StepScope to your context. However, your code still won't work once you've done that because you're returning an ItemReader for "myInputObjectItemReader" instead of ParameterSettingJdbcCursorItemReader . See the issue here for details on why that matters: Spring-batch @BeforeStep does not work with @StepScope

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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