How to Get Access to Job Parameters from Itemreader, in Spring Batch

How to get access to job parameters from ItemReader, in Spring Batch?

As was stated, your reader needs to be 'step' scoped. You can accomplish this via the @Scope("step") annotation. It should work for you if you add that annotation to your reader, like the following:

import org.springframework.batch.item.ItemReader;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component("foo-reader")
@Scope("step")
public final class MyReader implements ItemReader<MyData> {
@Override
public MyData read() throws Exception {
//...
}

@Value("#{jobParameters['fileName']}")
public void setFileName(final String name) {
//...
}
}

This scope is not available by default, but will be if you are using the batch XML namespace. If you are not, adding the following to your Spring configuration will make the scope available, per the Spring Batch documentation:

<bean class="org.springframework.batch.core.scope.StepScope" />

How to access jobparameter from ItemReader class of Spring batch job in spring boot web application

@Bean
public ItemReader reader() {
...
}

should be changed to

@Bean
public ItemStreamReader reader() {
...
}

or even more specific

@Bean
public FlatFileItemReader reader() {
...
}

Step definition should be changed as well to

@Bean
public Step step1(StepBuilderFactory stepBuilderFactory,
ItemStreamReader reader, ItemWriter writer,
ItemProcessor processor) {

}

Why is that necessary?

If an itemReader implements the ItemStream Interface (or ItemStreamReader) Spring will treat it as a such.

see https://docs.spring.io/spring-batch/reference/html/readersAndWriters.html#delegatePatternAndRegistering

A reader, writer, or processor that is directly wired into the Step
will be registered automatically if it implements ItemStream or a
StepListener interface.

that means spring will call the open, update and close methods

similar problem at Spring Batch: org.springframework.batch.item.ReaderNotOpenException: Reader must be open before it can be read

JobParameters from Spring Batch

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

I would try the following:

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

@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 @Value that is not @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...
}

Access job filename parameter in SkipPolicy of Spring Batch

Debugging how Spring Batch inject the parameters I found the solution.

I just need to add @StepScope in the class and create the variable where I want to inject the parameter:

@Component
@StepScope
@RequiredArgsConstructor
public class FileVerificationSkipper implements SkipPolicy {

@Value("#{jobParameters['input.file.name']}")
private String inputFile;

...

}

Access job parameter in ItemReader (spring-batch using grails)

You can define a bean in your spring-batch context:

<bean id="executionContext" class="com.xxx.ExecutionContextImpl" scope="step" >
<property name="toDate" value="#{jobParameters['toDate']}" />
<property name="fromDate" value="#{jobParameters['fromDate']}" />
</bean>

And then inject the executionContext in your ItemReader to have acces to your job parameters variables.

How to get Job parameteres in to item processor using spring Batch annotation

1) Put a scope annotation on your data processor i.e.

@Scope(value = "step") 

2) Make a class instance in your data processor and inject the job parameter value by using value annotation :

@Value("#{jobParameters['fileName']}")
private String fileName;

Your final Data processor class will look like:

@Scope(value = "step")
public class DataItemProcessor implements ItemProcessor<InputData, OutPutData> {

@Value("#{jobParameters['fileName']}")
private String fileName;

public OutPutData process(final InputData inputData) throws Exception {

// i want to get job Parameters here ????
System.out.println("Job parameter:"+fileName);

}

public void setFileName(String fileName) {
this.fileName = fileName;
}


}

In case your data processor is not initialized as a bean, put a @Component annotation on it:

@Component("dataItemProcessor")
@Scope(value = "step")
public class DataItemProcessor implements ItemProcessor<InputData, OutPutData> {


Related Topics



Leave a reply



Submit