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);
}
}
<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);
答案 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
值忽略。