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
Java.Lang.Noclassdeffounderror: Com/Fasterxml/Jackson/Databind/Exc/Invaliddefinitionexception
How to Run Single Cucumber Feature Files Through Command Prompt and Through Jenkins Using Maven
How to Mock Resultset and Populate It Using Mockito in Java
Multiple Scanner Inputs (Java)
How to Combine Date and Time into a Single Object
How to Subtract Number of Days from Current Date in Hql Query
Use Only One Bufferedreader Object to Read Multiple Files in Java
How to Encrypt a String/Stream With Bouncycastle Pgp Without Starting With a File
How to Apply Spring Boot Filter Based on Url Pattern
Spring MVC - Get Httpservletresponse Body
How to Avoid 302 Response on Https Spring Security Unit Test
Spring Boot Return 204 No-Content When List Is Empty
Prevent Empty Values on String Split
Every Digits in Number of a Range Should Be Is Divisible by N
This Program Is About String Compression in Java
Convert to Int from String of Numbers Having Comma
Run Gradle Task With Spring Profiles (Integration Tests)
Testing Two Json Objects for Equality Ignoring Child Order in Java