2014-03-01 147 views
3

我正在使用Spring Batch设置作业服务器。我的JdbcCursorItemReader需要使用sql进行配置,这个sql会在每个作业运行的基础上进行更改。由于sql的变化,我希望读者拥有@StepScope,因此我不需要担心sql的状态。如何使用基于java的配置来配置Spring批处理StepScope?

所以我设置的一类这样的:

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 
@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应用配置中,如下所示: <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(); 
} 

...但是当我做我上有没有关系StepScope豆类应用程序在启动过程中获取各种NPE上的。

在此先感谢。

+0

[This](https://github.com/codecentric/spring-batch-javaconfig/blob/master/src/test/java/de/codecentric/batch /FlatfileToDbWithParametersAutowiringJobTests.java)似乎与您要做的相似。作者写了一个[blog](https://blog.codecentric.de/en/2013/06/spring-batch-2-2-javaconfig-part-2-jobparameters-executioncontext-and-stepscope/)来解释。 – Alex

回答

1

您必须注册范围ApplicationContext。通常情况下,当您使用@EnableBatchProcessing时,会为您完成。你是否这样做(将该注释添加到你的@Configurations之一中)?

+0

我没有使用'@ EnableBatchProcessing'注释。我最初尝试过,但遇到问题,因为我在应用程序中有4个数据源。我试图为每个数据源创建一个独特的BatchConfigurer - 每个都带有@ EBP - 但我仍然得到关于多个数据源的相同错误。所以我想我要找的是在设置“@ EBP”时,看看在封面底下启用了StepScope,然后将其添加到我的配置中,而不是“@ EBP”。或者,如果您知道如何解决由@ EBP创建的多个数据源问题,那也可以。 –

+0

为什么你需要4个'BatchConfigurers'?其中一个'DataSources'必须用于批处理存储库。如果你能以某种方式识别它(例如,调用“dataSource”或将其标记为@ @ Primary),你可以编写一个'BatchConfigurer'来创建一个'JobRepository'。 –

+0

对DefaultBatchConfigurer的一点调查显示它需要数据源来存储作业回购。所以我用[这个问题]的答案(http://stackoverflow.com/questions/17090739/spring-batch-2-2-javaconfig) - 虽然使用“@Resource(name =”myDataSource“)'注释,而不是'@ Autowired' - 帮助设置。这让我使用了我的ItemReader bean上的'@ StepScope'。我仍然需要在范围注释中提供TARGET_CLASS的proxyMode,否则Tomcat不会启动。 –

0

对戴夫关于使用@EanbleBatchProcesssing的观点+1。这将为您的上下文添加StepScope。但是,一旦你完成了这个工作,你的代码仍然无法工作,因为你要为“myInputObjectItemReader”而不是ParameterSettingJdbcCursorItemReader返回一个ItemReader。请参阅此处的问题以了解为什么重要的详细信息:Spring-batch @BeforeStep does not work with @StepScope

+0

欣赏头。返回类型已被修改并运行良好。 –

相关问题