Java 来自 Spring Batch 的 JobParameters

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27862027/
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-11 05:10:19  来源:igfitidea点击:

JobParameters from Spring Batch

javaspringspring-batch

提问by pojo-guy

I am trying to inject job parameters into a custom ItemReader. I have reviewed all of the StackOverflow notes on the subject (example: How to get access to job parameters from ItemReader, in Spring Batch?), and I see this is a common pain point that is mostly unresolved. I am hoping that a spring guru (@Michael Minella anyone) will see this and have some insight.

我正在尝试将作业参数注入自定义 ItemReader。我已经查看了有关该主题的所有 StackOverflow 说明(例如:如何在 Spring Batch 中从 ItemReader 访问作业参数?),我发现这是一个常见的痛点,但大部分都没有解决。我希望春季大师(@Michael Minella 任何人)会看到这一点并有一些见解。

I have got as far as determining that the jobparameters are available about one out of 10 runs, even with no code or configuration changes. This is a case of a random success rather than a random failure, so it's proving hard to track down.

我已经确定作业参数在大约十分之一的运行中可用,即使没有代码或配置更改。这是随机成功而不是随机失败的情况,因此证明很难追踪。

I dug into the spring code with the debugger, and determined that when this fails, no bean of the name jobParameters is registered in Spring at the time that the injection is taking place.

我用调试器挖掘了 spring 代码,并确定当这个失败时,在注入发生时没有在 Spring 中注册名称为 jobParameters 的 bean。

I am using Spring 4.1.4 with spring-batch 3.0.2 and spring-data-jpa 1.7.1 and spring-data-commons 1.9.1, running in java 8.

我正在使用 Spring 4.1.4 和 spring-batch 3.0.2 和 spring-data-jpa 1.7.1 和 spring-data-commons 1.9.1,在 java 8 中运行。

Java class

Java类

@Component("sourceSelectionReader")
@Scope("step")
public class SourceSelectionReaderImpl  
implements ItemReader<MyThing> {
    private Map<String,Object> jobParameters;

// ... snip ...


    @Autowired
    @Lazy
    @Qualifier(value="#{jobParameters}")
    public void setJobParameters(Map<String, Object> jobParameters) {
        this.jobParameters = jobParameters;
    }
}

Job launch parameters:

作业启动参数:

launch-context.xml job1 jobid(long)=1

launch-context.xml (minus the fluff):

启动上下文.xml(减去绒毛):

<context:property-placeholder location="classpath:batch.properties" />

<context:component-scan base-package="com.maxis.maximo.ilm" />

<jdbc:initialize-database data-source="myDataSource"  enabled="false">
    <jdbc:script location="${batch.schema.script}" />
</jdbc:initialize-database>

<batch:job-repository id="jobRepository" 
    data-source="myDataSource"
    transaction-manager="transactionManager"
    isolation-level-for-create="DEFAULT"
    max-varchar-length="1000"/>

<import resource="classpath:/META-INF/spring/module-context.xml" />

Module-context.xml (minus the fluff):

Module-context.xml(减去绒毛):

<description>Example job to get you started. It provides a skeleton for a typical batch application.</description>

<import resource="classpath:/META-INF/spring/hibernate-context.xml"/>
<import resource="classpath:/META-INF/spring/myapp-context.xml"/>

<context:component-scan base-package="com.me" />
<bean class="org.springframework.batch.core.scope.StepScope" />

<batch:job id="job1">
    <batch:step id="step0002"  >            
        <batch:tasklet transaction-manager="transactionManager" start-limit="100" >
            <batch:chunk reader="sourceSelectionReader" writer="selectedDataWriter" commit-interval="1" />
        </batch:tasklet>
    </batch:step>
</batch:job> 

采纳答案by wassgren

The important steps to get Job Parameters to work is to define the StepScopebean and to make sure that your reader is a @StepScopecomponent.

使作业参数起作用的重要步骤是定义StepScopebean 并确保您的阅读器是一个@StepScope组件。

I would try the following:

我会尝试以下方法:

First make sure that there is a step-bean defined. This is nice to setup using Java Configuration:

首先确保定义了一个 step-bean。使用 Java 配置进行设置很不错:

@Configuration
public class JobFrameworkConfig {  
    @Bean
    public static StepScope scope() {
        return new StepScope();
    }
    // jobRegistry, transactionManager etc...
}

Then, make sure that your bean is step-scoped by the use of the @StepScope-annotation (almost as in your example). Inject a @Valuethat is not @Lazy.

然后,通过使用@StepScope-annotation确保您的 bean 是步进范围的(几乎与您的示例一样)。注入一个@Value不是@Lazy.

@Component("sourceSelectionReader")
@StepScope // required, also works with @Scope("step")
public class SourceSelectionReaderImpl implements ItemReader<MyThing> {
    private final long myParam;

    // Not lazy, specified param name for the jobParameters
    @Autowired
    public SourceSelectionReaderImpl(@Value("#{jobParameters['myParam']}") final long myParam) {
        this.myParam = myParam;
    }

    // the rest of the reader...
}

回答by Pavan

Try add @DependsOn("jobParameters") after @Component("sourceSelectionReader")

尝试在 @Component("sourceSelectionReader") 之后添加 @DependsOn("jobParameters")