Spring Batch Javaconfig - parameterize commit-inte

2019-02-18 15:51发布

问题:

with Spring Batch xml based configuration you can parameterize the commit-interval / chunk size like:

<job id="basicSimpleJob" 
     xmlns="http://www.springframework.org/schema/batch">
    <step id="basicSimpleStep" >
        <tasklet>
            <chunk
                reader="reader" 
                processor="processor" 
                writer="writer" 
                commit-interval="#{jobParameters['commit.interval']}">
            </chunk>
        </tasklet>
    </step>
</job>

with javaconfig based configuration it could look like

@Bean
public Step step(
        ItemStreamReader<Map<String, Object>> reader,
        ItemWriter<Map<String, Object>> writer,
        @Value("#{jobParameters['commit.interval']}") Integer commitInterval
) throws Exception {
    return steps
            .get("basicSimpleStep")
            .<Map<String, Object>, Map<String, Object>>chunk(commitInterval)
            .reader(reader)
            .processor(new FilterItemProcessor())
            .writer(writer)
            .build();
}

but it does not work, i get either

Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Property or field 'jobParameters' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public?

or - while using @StepScope for the step bean -

Caused by: java.lang.IllegalStateException: No context holder available for step scope

i know i have a working stepscope, other stepscoped beans work(defined inside same class as step)

right now i use a CompletionPolicy which does work with stepScope but i would like to know if someone got it to work the "normal" way or if it's time for a JIRA ticket

... which is created at https://jira.spring.io/browse/BATCH-2263

回答1:

Adding @JobScope annotation to Step definition is working in Spring Batch 3:

@Bean
@JobScope
public Step step(
        ItemStreamReader<Map<String, Object>> reader,
        ItemWriter<Map<String, Object>> writer,
        @Value("#{jobParameters['commit.interval']}") Integer commitInterval
)

This will initialize the step bean at job execution, so late binding of jobParameters is working in this case.



回答2:

I have poor confidence with JavaConfig and - maybe - this can be an issue only for commit-interval during late binding for java configuration (in SB ChunkElementParser.java source there are few lines of code that checks for commit-interval starts with a # and inject a SimpleCompletionPolicy step scoped); you can try injecting a StepExecutionSimpleCompletionPolicy and check if this solution works.

Also, I have never tried late binding commit-interval with xml config but there is a [opened ticket with title Commit Interval not working as intended when used in Late Binding

As last chance, if you are using version 3.0, you can also annotate step with @JobScope and check if this solution works.