我是一个春季批次,其中包含 reader-> processor-> writer 。
传递的数据为黑白,类型为Emp
:
class Emp {
iny id;
String name;
EmpTypeEnum empType; // HR, Dev, Tester, etc.
// getters and setters
}
从Reader
的CSV文件中读取一个简单的批处理数据,Processor
&输出CSV文件由Writer
写入。
但是除了这个输出CSV文件之外,我想生成一个辅助输出文件,它只包含每个EmpType
的计数,即HR,Dev&的总数。测试仪。
我在考虑仅在processor
内执行计数,例如:
public class EmpItemProcessor implements ItemProcessor<Emp, Emp> {
int countHr;
int countDev;
int countTester;
@Override
public Person process(final Emp emp) throws Exception {
if (item.getEmpType.equals(EmpTypeEnum.HR) {
countHr++;
} else if // .....
// other processor on emp
return emp;
}
}
但是你可以看到我只能从Emp
返回Processor
,那么如何从处理器&amp;中传递 countHr,countDev等。用它来创建辅助文件?
请建议。如果您认为任何其他方法会更好,请建议。
感谢
答案 0 :(得分:3)
您可以使用ItemWriteListener
和JobExecutionListenerSupport
。
定义一个ItemWriteListener,每次调用你的编写器后都会调用它。
在此Listener中,每次都在执行上下文中更新计数器
编写一个JobExecutionListener,它将在整个作业完成后调用,您可以从执行上下文中读取值并进行进一步处理。
@Component
@JobScope
public class EmployeeWriteListener implements ItemWriteListener<Emp> {
@Value("#{jobExecution.executionContext}")
private ExecutionContext executionContext;
@Override
public void afterWrite(final List<? extends Emp> paramList) {
final int counter =
this.executionContext.getInt("TOTAL_EXPORTED_ITEMS", 0);
this.executionContext.putInt("TOTAL_EXPORTED_ITEMS", counter + 1);
}
}
}
@Component
@JobScope
public class EmployeeNotificationListener extends JobExecutionListenerSupport {
@Override
public void afterJob(final JobExecution jobExecution) {
jobExecution.getExecutionContext()
.getInt("TOTAL_EXPORTED_ITEMS")
...................
}
}
在宣布步骤和工作时,您应该注册这些听众。
this.jobBuilders.get("someJob").incrementer(new RunIdIncrementer()).listener(new EmployeeNotificationListener())
.flow(this.getSomeStep()).end().build();
//instead of new(..) you should Autowire listener
public Step getSomeStep() {
return stepBuilders.get("someStep").<X, Y>chunk(10)
.reader(this.yourReader).processor(this.yourProcessor)
.writer(this.yourProcessor).listener(this.EmployeeWriteListener)
.build();
}
答案 1 :(得分:1)
基本上你需要多个ItemWriter
来处理两个不同的写作任务。您可以轻松使用CompositeItemWriter
,它可以在其中保存不同ItemWriter的列表。在每个项目上,它将调用所有ItemWriter
。
在你的情况下,
制作两个FlatFileItemWriter
- 一个用于普通的CSV输出&amp;其他的统计数据。
然后创建CompositeItemWriter<Emp>
对象,并使用此方法将这些FlatFileItemWriter<Emp>
添加到其中 - public void setDelegates(List<ItemWriter<Emp>> delegates)
在步骤<{p>
CompositeItemWriter
使用此ItemWriter
醇>
因此,当您CompositeItemWriter
被调用时,它将委托给ItemWriter
,以便您添加到列表中。
完成工作:)