我正在开发一个 Spring 批处理项目,在该项目中我正在读取学生列表,对其进行处理并编写它。
现在我保持简单,处理只是返回学生并写入只是打印它。
我期望每次运行该步骤时都会看到输出,但当该步骤第一次运行时我只看到一次。下面是输出
2020-04-03 01:33:16.153 INFO 14710 --- [ main] o.s.batch.core.job.SimpleStepHandler : Executing step: [xxxx]
[Student{id=1, name='ABC'}]
as
[Student{id=2, name='DEF'}]
as
[Student{id=3, name='GHI'}]
as
2020-04-03 01:33:16.187 INFO 14710 --- [ main] o.s.batch.core.step.AbstractStep : Step: [xxxx] executed in 33ms
2020-04-03 01:33:16.190 INFO 14710 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : Job: [SimpleJob: [name=readStudents]] completed with the following parameters: [{}] and the following status: [COMPLETED] in 52ms
job triggered
2020-04-03 01:33:17.011 INFO 14710 --- [ scheduling-1] o.s.b.c.l.support.SimpleJobLauncher : Job: [SimpleJob: [name=readStudents]] launched with the following parameters: [{time=1585857797003}]
2020-04-03 01:33:17.017 INFO 14710 --- [ scheduling-1] o.s.batch.core.job.SimpleStepHandler : Executing step: [xxxx]
2020-04-03 01:33:17.022 INFO 14710 --- [ scheduling-1] o.s.batch.core.step.AbstractStep : Step: [xxxx] executed in 4ms
2020-04-03 01:33:17.024 INFO 14710 --- [ scheduling-1] o.s.b.c.l.support.SimpleJobLauncher : Job: [SimpleJob: [name=readStudents]] completed with the following parameters: [{time=1585857797003}] and the following status: [COMPLETED] in 11ms
我还注意到,第一次作业中没有参数,之后就有了参数。而我每次运行作业时都会提供作业参数。
配置文件
@EnableBatchProcessing
public class Config {
private JobRunner jobRunner;
public Config(JobRunner jobRunner){
this.jobRunner = jobRunner;
}
@Scheduled(cron = "* * * * * *")
public void scheduleJob() throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException {
System.out.println("job triggered");
jobRunner.runJob();
}
}
@Configuration
public class JobConfig {
@Bean
public Job job(JobBuilderFactory jobBuilderFactory,
StepBuilderFactory stepBuilderFactory,
ItemReader<Student> reader,
ItemProcessor<Student, Student> processor,
ItemWriter<Student> writer) {
Step step = stepBuilderFactory.get("xxxx")
.<Student, Student>chunk(1)
.reader(reader)
.processor(processor)
.writer(writer)
.build();
return jobBuilderFactory
.get("readStudents")
.start(step)
.build();
}
@Bean
public ItemReader<Student> reader() {
return new InMemoryStudentReader();
}
}
作业运行程序文件
public class JobRunner {
private Job job;
private JobLauncher simpleJobLauncher;
@Autowired
public JobRunner(Job job, JobLauncher jobLauncher) {
this.simpleJobLauncher = jobLauncher;
this.job = job;
}
public void runJob() throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException {
JobParameters jobParameters =
new JobParametersBuilder()
.addLong("time",System.currentTimeMillis()).toJobParameters();
simpleJobLauncher.run(job, jobParameters);
}
}
内存中的学生读者
public class InMemoryStudentReader implements ItemReader<Student> {
private int nextStudentIndex;
private List<Student> studentData;
public InMemoryStudentReader() {
initialize();
}
private void initialize() {
Student s1 = new Student(1, "ABC");
Student s2 = new Student(2, "DEF");
Student s3 = new Student(3, "GHI");
studentData = Collections.unmodifiableList(Arrays.asList(s1, s2,s3));
nextStudentIndex = 0;
}
@Override
public Student read() throws Exception {
Student nextStudent = null;
if (nextStudentIndex < studentData.size()) {
nextStudent = studentData.get(nextStudentIndex);
nextStudentIndex++;
}
return nextStudent;
}
}
最佳答案
因为您在 InMemoryStudentReader
构造函数中调用 initialize()
。 Spring 仅初始化 InMemoryStudentReader 一次并将其连接到您的作业。第一次运行后,nextStudentIndex
不会重置为 0。因此,下次作业运行时,您的阅读器将无法再阅读。
如果您希望它正常工作,则应在开始作业时将 nextStudentIndex
重置为 0。
关于java - Spring Batch 步骤未执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61000255/