Spring Batch Framework writer 仍在处理 reader 遇到 Nullpointerexception
Spring Batch Framework writer still processing even the reader encountered Nullpointerexception
我的批处理作业reader return Nullpointerexception,但文件仍然生成。为什么会这样?我以为编写器只会在 reader 和处理器完成该过程时被调用?
<bean id="myWriter" class="org.springframework.batch.item.file.FlatFileItemWriter" >
<property name="resource"
value="file:D:\out\file.txt" />
<property name="lineAggregator">
<bean
class="org.springframework.batch.item.file.transform.PassThroughLineAggregator" />
</property>
<property name="footerCallback" ref="myCustomWriter" />
<!-- <property name="headerCallback" ref="myCustomWriter" /> -->
</bean>
<bean id="myCustomWriter" class="com.spring.batch.MyWriter"
scope="step">
<property name="delegate" ref="myWriter" />
<property name="stepContext" value="#{stepExecution.stepName}" />
</bean>
生成是什么意思?它是空的,还是包含数据?
在执行步骤之前,spring-batch 框架调用 Reader 和 Writers 的 ItemStream 接口的 open() 方法(前提是您有 Reader 和实现 ItemStream 的作者)。
查看 FlatFileItemWriter 实现。您会看到它实现了 ItemStream,因此具有 open() 方法的实现。
更详细地查看代码,您会看到 open() 调用 doOpen(),后者调用 HeaderCallback(如果已定义)。因此,在对 writer-method 或 Reader 的 reader-method 的任何调用发生之前,生成文件并写入 header。
建议大家在Reader和Writer的open Methods下打断点,在spring-batch框架的代码中调试一下。它会让您更好地了解正在发生的事情 "under the hood"。
这可能超出了您最初问题的范围,但如果您想更深入地研究 "transaction handling" 中的某个步骤,可以阅读 Tobias Flöhre 撰写的三篇涵盖该主题的优秀博客文章:
步骤上的提交间隔控制编写器何时被调用。它的工作方式是
- Reader 被调用来批量读取 N 项(这就是它实际实现的方式,概念上应该读取一项然后处理一项)
- 逐一处理N项中的每一项
- 在提交计数时,一次写入所有 N 项。
这在章节的文档中有详细解释 - http://docs.spring.io/spring-batch/reference/html/configureStep.html
- 页眉回调和页脚回调也将在写入器初始化期间首次写入文件之前的某个时间调用
我的批处理作业reader return Nullpointerexception,但文件仍然生成。为什么会这样?我以为编写器只会在 reader 和处理器完成该过程时被调用?
<bean id="myWriter" class="org.springframework.batch.item.file.FlatFileItemWriter" >
<property name="resource"
value="file:D:\out\file.txt" />
<property name="lineAggregator">
<bean
class="org.springframework.batch.item.file.transform.PassThroughLineAggregator" />
</property>
<property name="footerCallback" ref="myCustomWriter" />
<!-- <property name="headerCallback" ref="myCustomWriter" /> -->
</bean>
<bean id="myCustomWriter" class="com.spring.batch.MyWriter"
scope="step">
<property name="delegate" ref="myWriter" />
<property name="stepContext" value="#{stepExecution.stepName}" />
</bean>
生成是什么意思?它是空的,还是包含数据?
在执行步骤之前,spring-batch 框架调用 Reader 和 Writers 的 ItemStream 接口的 open() 方法(前提是您有 Reader 和实现 ItemStream 的作者)。
查看 FlatFileItemWriter 实现。您会看到它实现了 ItemStream,因此具有 open() 方法的实现。
更详细地查看代码,您会看到 open() 调用 doOpen(),后者调用 HeaderCallback(如果已定义)。因此,在对 writer-method 或 Reader 的 reader-method 的任何调用发生之前,生成文件并写入 header。
建议大家在Reader和Writer的open Methods下打断点,在spring-batch框架的代码中调试一下。它会让您更好地了解正在发生的事情 "under the hood"。
这可能超出了您最初问题的范围,但如果您想更深入地研究 "transaction handling" 中的某个步骤,可以阅读 Tobias Flöhre 撰写的三篇涵盖该主题的优秀博客文章:
步骤上的提交间隔控制编写器何时被调用。它的工作方式是
- Reader 被调用来批量读取 N 项(这就是它实际实现的方式,概念上应该读取一项然后处理一项)
- 逐一处理N项中的每一项
- 在提交计数时,一次写入所有 N 项。
这在章节的文档中有详细解释 - http://docs.spring.io/spring-batch/reference/html/configureStep.html
- 页眉回调和页脚回调也将在写入器初始化期间首次写入文件之前的某个时间调用