如何使用基于 Java 的配置来配置 Spring Batch StepScope?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22108315/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 13:38:32  来源:igfitidea点击:

How can I configure Spring Batch StepScope using java-based configuration?

javaspringspring-batch

提问by Samuel Dupont

I'm setting up a job server using Spring Batch. My JdbcCursorItemReader needs to be configured with sql that changes on a per-job run basis. Because the sql changes, I want the reader to have @StepScope so I don't need to worry about sql statefulness.

我正在使用 Spring Batch 设置作业服务器。我的 JdbcCursorItemReader 需要使用 sql 配置,该 sql 在每个作业运行的基础上更改。因为sql变了,我希望读者有@StepScope 这样我就不用担心sql有状态了。

So I've setup a class like this:

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

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;
    }
}

The idea is that I pass sql parameters to the object via JobParameters and use String.format to fill in the dynamically-changing sql.

这个想法是我通过 JobParameters 将 sql 参数传递给对象,并使用 String.format 来填充动态变化的 sql。

I am using Java-based configuration throughout my server. My bean for one instance of my ItemReader looks like:

我在整个服务器中使用基于 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;
}

When I start up my server and run the Spring Batch job, I get this error: java.lang.IllegalStateException: No Scope registered for scope 'step'

当我启动服务器并运行 Spring Batch 作业时,出现此错误: java.lang.IllegalStateException: No Scope registered for scope 'step'

I've read elsewhere that in order to be able to use StepScope, one needs to first add it to the xml app configuration like this : <bean class="org.springframework.batch.core.scope.StepScope" />

我在其他地方读到过,为了能够使用 StepScope,首先需要将它添加到 xml 应用程序配置中,如下所示: <bean class="org.springframework.batch.core.scope.StepScope" />

But since I'm using Java-based configuration, that's not an option.

但是由于我使用的是基于 Java 的配置,所以这不是一个选项。

So how do I register the StepScope via a Java-based config? I've tried this:

那么如何通过基于 Java 的配置注册 StepScope?我试过这个:

@Bean
public org.springframework.batch.core.scope.StepScope stepScope() {
    return new org.springframework.batch.core.scope.StepScope();
}

... but when I do I get all sorts of NPEs during app startup on beans that have no relation to StepScope.

...但是当我这样做时,我会在应用程序启动期间在与 StepScope 无关的 bean 上获得各种 NPE。

Thanks in advance.

提前致谢。

采纳答案by Dave Syer

You have to register the scope with the ApplicationContext. Normally that would be done for you when you use @EnableBatchProcessing. Did you do that (add that annotation to one of your @Configurations)?

您必须使用ApplicationContext. 通常,当您使用@EnableBatchProcessing. 您这样做了吗(将该注释添加到您的其中之一@Configurations)?

回答by Michael Minella

+1 to Dave's point about using @EanbleBatchProcesssing. That will add a StepScopeto your context. However, your code still won't work once you've done that because you're returning an ItemReader for "myInputObjectItemReader" instead of ParameterSettingJdbcCursorItemReader. See the issue here for details on why that matters: Spring-batch @BeforeStep does not work with @StepScope

+1 Dave 关于使用@EanbleBatchProcesssing 的观点。这将为StepScope您的上下文添加一个。但是,一旦您完成此操作,您的代码仍然无法工作,因为您返回的是“myInputObjectItemReader”的 ItemReader 而不是ParameterSettingJdbcCursorItemReader. 有关原因的详细信息,请参阅此处的问题:Spring-batch @BeforeStep 不适用于 @StepScope