You can do that by passing these properties as job parameters (those are best passed as non-identifying job parameters in this case) and late-bind them in your reader at runtime. Here is an example:
@Bean
@StepScope
public ItemReader<String[]> itemReader(
@Value("#{jobParameters['fileName']}") String fileName,
@Value("#{jobParameters['columnNames']}") String columnNames
) {
return new FlatFileItemReaderBuilder<String[]>()
.name("hacReader")
//put file here
.resource(new FileSystemResource(fileName))
.lineMapper(new DefaultLineMapper<String[]>() {{
setLineTokenizer(new DelimitedLineTokenizer() {{
//put column names here
setNames(columnNames.split(","));
}});
}})
.build();
}
With this setup, the reader will be dynamically configured with the fileName and columnNames specified as job parameters:
JobParameters jobParameters = new JobParametersBuilder()
.addString("fileName", "/path/to/input/file")
.addString("columnNames", "column1,column2,column5")
.toJobParameters();
Hope this helps.
Answer from Mahmoud Ben Hassine on Stack Overflowjava - Dynamically configure a Job in spring-batch - Stack Overflow
Spring Batch - How to access JobParameters or JobExecution for a dynamically created Job? - Stack Overflow
How do I set JobParameters in spring batch with spring-boot - Stack Overflow
java - running a job in foreach loop with dynamic parameters spring batch - Stack Overflow
Parse in job parameters from the command line and then create and populate JobParameters.
public JobParameters getJobParameters() {
JobParametersBuilder jobParametersBuilder = new JobParametersBuilder();
jobParametersBuilder.addString("dest", <dest_from_cmd_line);
jobParametersBuilder.addDate("date", <date_from_cmd_line>);
return jobParametersBuilder.toJobParameters();
}
Pass them to your job via JobLauncher -
JobLauncher jobLauncher = context.getBean(JobLauncher.class);
JobExecution jobExecution = jobLauncher.run(job, jobParameters);
Now you can access them using code like -
@Bean
@StepScope
public Resource destFile(@Value("#{jobParameters[dest]}") String dest) {
return new FileSystemResource(dest);
}
Or in a @Configuration class that is configuring Spring Batch Job artifacts like - ItemReader, ItemWriter, etc...
@Bean
@StepScope
public JdbcCursorItemReader<MyPojo> reader(@Value("#{jobParameters}") Map jobParameters) {
return new MyReaderHelper.getReader(jobParameters);
}
I managed to get this working by simply annotating my bean as follows :
@Bean
@StepScope
public Resource destFile(@Value("#{jobParameters[dest]}") String dest) {
return new FileSystemResource(dest);
}
There are various questions.
1. To disable starting all jobs automatically on startup just configure this Spring Boot property:
spring.batch.job.enabled=false # Do not execute all Spring Batch jobs in the context on startup.
2. You would run job like this:
java -Dspring.batch.job.names=prepareTeaJob -jar target/0910-job-parameters-cli-0.0.2-SNAPSHOT.jar sugarAmount="no sugar"
sugar amount there is Job parameter. Full example belonging to this listing is hosted in my Github Repository here. BTW, there are much more examples covering these various Spring Batch topics if you are learning Spring Batch.
3. Not sure what you are referring to as "ApplicationReadyEvent". AFAIK job should be executed after the Spring context it fully initialized.
My solution was the following:
Set the spring.batch.job.enabled property to false - this prevented jobs to start when the context was setup
Get the JobLauncher out of the context and run any Job myself:
SpringApplication app = new SpringApplication(BatchProcessingServiceStarter.class); app.setWebEnvironment(false); ConfigurableApplicationContext ctx=app.run(args); JobLauncher jobLauncher = ctx.getBean(JobLauncher.class); JobParameters jobParameters = new JobParametersBuilder() .addDate("date", new Date()) .toJobParameters(); if(!"1".equals(args[0])){ jobLauncher.run(ctx.getBean("BatchConfiguration2", Job.class), jobParameters); } else { jobLauncher.run(ctx.getBean("BatchConfiguration1", Job.class), jobParameters); }