我正在使用Spring Batch设置作业服务器。我的JdbcCursorItemReader需要配置sql,它在每个作业运行的基础上更改。因为sql发生了变化,我希望读者能够使用@StepScope,所以我不需要担心sql状态。
所以我设置了这样一个类:
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;
}
}
我的想法是通过JobParameters将sql参数传递给对象,并使用String.format填写动态变化的sql。
我在整个服务器中使用基于Java的配置。我的ItemReader的一个实例的bean看起来像:
@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;
}
当我启动服务器并运行Spring Batch作业时,出现此错误:java.lang.IllegalStateException: No Scope registered for scope 'step'
我在其他地方读过,为了能够使用StepScope,首先需要将它添加到xml app配置中,如下所示:
<bean class="org.springframework.batch.core.scope.StepScope" />
但是因为我使用的是基于Java的配置,所以这不是一个选择。
那么如何通过基于Java的配置注册StepScope?我试过这个:
@Bean
public org.springframework.batch.core.scope.StepScope stepScope() {
return new org.springframework.batch.core.scope.StepScope();
}
...但是当我这样做的时候,在app启动期间,我会在与StepScope无关的bean上获得各种NPE。
提前致谢。
答案 0 :(得分:2)
您必须使用ApplicationContext
注册范围。通常,当您使用@EnableBatchProcessing
时,将会为您完成此操作。你做到了吗(将那个注释添加到你的@Configurations
之一)?
答案 1 :(得分:0)
+1 Dave关于使用@EanbleBatchProcesssing的观点。这会在您的上下文中添加StepScope
。但是,一旦完成该代码,您的代码仍然无效,因为您正在为“myInputObjectItemReader”而不是ParameterSettingJdbcCursorItemReader
返回ItemReader。请参阅此处的问题,了解重要原因的详细信息:Spring-batch @BeforeStep does not work with @StepScope