项读取器和项写入器
所有批处理都可以简单地描述为读取大量数据、执行某种计算或转换,并输出结果。Spring Batch 提供了三个关键接口来帮助进行批量读取和写入:ItemReader
、ItemProcessor
和 ItemWriter
。
小节摘要
📄️ ItemReader
虽然概念简单,但 ItemReader 是从许多不同类型的输入中提供数据的手段。最通用的例子包括:
📄️ ItemWriter
ItemWriter 在功能上与 ItemReader 类似,但操作相反。仍然需要定位、打开和关闭资源,但它们的不同之处在于 ItemWriter 是写入而不是读取。在数据库或队列的情况下,这些操作可能是插入、更新或发送。输出序列化的格式因每个批处理作业而异。
📄️ ItemStream
ItemReader 和 ItemWriter 都很好地服务于它们各自的目的,但它们之间有一个共同的关注点,需要另一个接口。一般来说,在批处理作业的范围内,读取器和写入器需要打开、关闭,并且需要一种持久化状态的机制。ItemStream 接口就服务于这个目的,如下例所示:
📄️ 委托模式与在步骤中注册
请注意,CompositeItemWriter 是 Spring Batch 中常见的委托模式的一个示例。这些委托本身可能实现了回调接口,例如 StepListener。如果它们确实实现了此类接口,并且作为作业中的步骤的一部分与 Spring Batch Core 一起使用,则几乎肯定需要手动将它们注册到步骤中。直接连接到步骤的读取器、写入器或处理器如果实现了 ItemStream 或 StepListener 接口,则会自动注册。但是,由于委托对步骤来说是未知的,因此需要将它们注入为监听器或流(如果合适的话,可以同时注入为两者)。
🗃️ Flat Files
3 个项目
📄️ XML 项读取器和写入器
Spring Batch 为读取 XML 记录并将其映射到 Java 对象以及将 Java 对象写入为 XML 记录提供了事务基础设施。
📄️ JSON 项读取器和写入器
Spring Batch 提供了对以下格式的 JSON 资源进行读取和写入的支持:
📄️ 多文件输入
在一个步骤中处理多个文件是一个常见的需求。假设这些文件具有相同的格式,MultiResourceItemReader 支持这种类型的输入,无论是 XML 还是平面文件处理。考虑目录中的以下文件:
📄️ 数据库
像大多数企业应用风格一样,数据库是批处理的核心存储机制。然而,批处理与其他应用风格的不同之处在于系统必须处理的数据集的规模。如果一条 SQL 语句返回了 1 百万行,结果集可能会将所有返回的结果保存在内存中,直到所有行都被读取完毕。Spring Batch 为这一问题提供了两种类型的解决方案:
📄️ 重用现有服务
批处理系统通常与其他应用程序风格结合使用。最常见的联机系统,但也可能通过移动每种应用程序风格使用的必要批量数据来支持集成甚至厚客户端应用程序。出于这个原因,许多用户希望在其批处理作业中重用现有的 DAO 或其他服务。Spring 容器本身通过允许注入任何必要的类,使得这相对容易。然而,在某些情况下,现有的服务需要充当 ItemReader 或 ItemWriter,无论是为了满足另一个 Spring Batch 类的依赖关系,还是因为它确实是某个步骤的主要 ItemReader。为每个需要包装的服务编写适配器类是相当简单的,但由于这是一个常见的需求,Spring Batch 提供了实现:ItemReaderAdapter 和 ItemWriterAdapter。这两个类通过调用委托模式实现了标准的 Spring 方法,并且设置起来相对简单。
📄️ 防止状态持久化
默认情况下,所有的 ItemReader 和 ItemWriter 实现都会在提交之前将其当前状态存储在 ExecutionContext 中。然而,这并不总是理想的行为。例如,许多开发人员选择通过使用进程指示器来使他们的数据库读取器具备“可重跑性”。通过在输入数据中添加一个额外的列,来指示该数据是否已被处理。当某个特定记录被读取(或写入)时,已处理标志会从 false 转变为 true。然后,SQL 语句可以在 where 子句中包含一个额外的条件,例如 where PROCESSED\_IND = false,从而确保在重启时仅返回未处理的记录。在这种情况下,最好不存储任何状态(例如当前行号),因为这些状态在重启时是无关紧要的。因此,所有读取器和写入器都包含一个 saveState 属性。
📄️ 创建自定义的 ItemReader 和 ItemWriter
到目前为止,本章讨论了Spring Batch中读写的基本契约以及一些常见的实现方式。然而,这些都相对比较通用,许多潜在场景可能无法通过现成的实现来覆盖。本节通过一个简单示例展示如何创建自定义的 ItemReader 和 ItemWriter 实现,并正确实现它们的契约。此外,ItemReader 还实现了 ItemStream,以说明如何使读取器或写入器具备可重启性。
📄️ 项读取器和写入器实现
在本节中,我们将向您介绍在前几节中尚未讨论过的读写器。