Spring Batch Partition:ItemReader Bean在@Value中有问题("#{stepExecutionContext [fromId]}")阅读

时间:2017-08-31 13:53:23

标签: java spring spring-data spring-batch

Spring批处理新手并尝试为大量数据输入实现分区。我已经检查了下面的解决方案,它与我的问题类似,但无法解决问题。

Spring Batch : Field or property 'stepExecutionContext' cannot be found

Spring Batch Partitioning inject stepExecutionContext parameter in itemReader

但我仍然有例外:

Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Property or field 'stepExecutionContext' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public?
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:224)
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:94)
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:81)
    at org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:51)
    at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:87)
    at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:120)
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:242)
    at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:161)
    ... 19 more

我的项目阅读器文件是这样的:

@Configuration
public class ProfileJobItemReader{

    @Value("#{stepExecutionContext[fromId]}")
    private int fromId;

    @Bean(name = "profileMongoItemReader")
    @StepScope
    public ItemReader<ProfileCollection> profileMongoItemReader()
            throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {

        System.out.println(fromId);
    }

}

我的xml文件是这样的:

<bean id="profileItemProcessor" class="...........ProfileProcessor" scope="step" />
<bean id="profileItemWriter" class="...........ProfileWriter" scope="step" />

.............

<bean id="rangePartitioner" class="...........ProfilePartitioner" />

<batch:job id="profileJob">
    <batch:step id="masterStep">
        <partition step="profileMainStep" partitioner="rangePartitioner">
            <handler grid-size="100" task-executor="taskExecutor" />
        </partition>
    </batch:step>
</batch:job>

<batch:step id="profileMainStep">
    <batch:tasklet task-executor="profileTaskExecutor" throttle-limit="30">
        <batch:chunk reader="profileMongoItemReader" processor="profileItemProcessor"
            writer="profileItemWriter" commit-interval="${profileCommitInterval}" />
    </batch:tasklet>
</batch:step>

我知道由于我的项目阅读器中的以下行而导致异常:

@Value("#{stepExecutionContext[fromId]}")

但是同样的语句在我的Processor类中有效(获得结果)。所以我想知道我在ItemReader类中缺少什么。请帮忙

Processor类中没有异常。我的处理器类如下:

public class ProfileProcessor implements ItemProcessor<ProfileCollection, ProfileCollection> {

    @Value("#{stepExecutionContext[name]}")
    private String threadName;

    @Override
    public ProfileCollection process(ProfileCollection item) throws Exception {
        System.out.println(threadName);

2 个答案:

答案 0 :(得分:0)

问题在于读者的@Configuration注释。在作业开始之前加载配置类。

只有在开始步骤后才能获得stepExecutionContext。 您的处理器类获得stepExecutionContext,因为它没有component/configuration注释。

答案 1 :(得分:0)

问题在于stepExecutionContext仅在@StepScope内部定义,因此您只能在stepSope内部访问它,如下所示:

@Configuration
public class ProfileJobItemReader{

@Bean(name = "profileMongoItemReader")
@StepScope
public ItemReader<ProfileCollection> profileMongoItemReader(@Value("#{stepExecutionContext[fromId]}") int fromId)
        throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {

    System.out.println(fromId);

   }
}

从调用方方法中,您可以传递null,该值将被您的stepExecutionContext值忽略。