1. Spring Batch简介

企业域内的许多应用程序都需要批量处理才能在关键任务环境中执行业务操作。这些业务包括:

  • 自动,复杂地处理大量信息,无需用户交互即可最有效地进行处理。这些操作通常包括基于时间的事件(例如月末计算,通知或通信)。

  • 定期应用非常大的数据集(例如,保险利益确定或费率调整)重复处理复杂的业务规则。

  • 从内部和外部系统接收的信息的集成,通常需要格式化,验证和以事务方式进行的处理到记录系统中。批处理用于每天为企业处理数十亿笔交易。

Spring Batch是一个轻量级的,全面的批处理框架,旨在使鲁棒的批处理应用程序的开发对于企业系统的日常运行至关重要。Spring Batch建立在人们期望的Spring框架特性(生产力,基于POJO的开发方法和普遍的易用性)的基础上,同时使开发人员在必要时可以轻松访问和利用更高级的企业服务。Spring Batch不是一个调度框架。商业空间和开放源代码空间中都有许多好的企业调度程序(例如Quartz,Tivoli,Control-M等)。它旨在与计划程序一起工作,而不是替换计划程序。

Spring Batch提供了可重用的功能,这些功能对于处理大量记录至关重要,包括日志记录/跟踪,事务管理,作业处理统计信息,作业重新启动,跳过和资源管理。它还提供了更高级的技术服务和功能,这些功能可以通过优化和分区技术实现超大量和高性能的批处理作业。Spring Batch可用于简单的用例(例如,将文件读入数据库或运行存储过程)以及复杂的大量用例(例如,在数据库之间移动大量数据,对其进行转换等)。上)。大量批处理作业可以高度可扩展的方式利用框架来处理大量信息。

1.1.背景

尽管开源软件项目和相关社区将更多的注意力集中在基于Web和基于微服务的体系结构框架上,但是仍然存在着对可重用体系结构框架的关注,以适应基于Java的批处理需求,尽管仍然需要继续处理此类问题。在企业IT环境中进行处理。缺乏标准的,可重复使用的批处理体系结构,导致在客户端企业IT功能内开发的许多一次性内部解决方案激增。

SpringSource(现为Pivotal)和埃森哲合作改变了这一点。埃森哲在实现批处理体系结构方面的动手行业和技术经验,SpringSource的深厚技术经验以及Spring久经验证的编程模型共同构成了一种自然而强大的合作伙伴关系,以创建旨在填补企业Java重要缺口的高质量,与市场相关的软件。两家公司都与许多客户合作,他们通过开发基于Spring的批处理体系结构解决方案来解决类似的问题。这提供了一些有用的附加细节和现实生活中的约束条件,有助于确保解决方案可以应用于客户提出的现实问题。

埃森哲为Spring Batch项目贡献了以前专有的批处理架构框架,以及用于推动支持,增强功能和现有功能集的提交者资源。埃森哲的贡献基于数十年来在使用最后几代平台构建批处理体系结构方面的经验:COBOL / Mainframe,C ++ / Unix,以及现在的Java / anywhere。

埃森哲与SpringSource之间的合作旨在促进软件处理方法,框架和工具的标准化,企业用户在创建批处理应用程序时可以始终利用它们。希望为企业IT环境提供标准的,经过验证的解决方案的公司和政府机构可以从Spring Batch中受益。

1.2.使用场景

典型的批处理程序通常:

  • 从数据库,文件或队列中读取大量记录。

  • 以某种方式处理数据。

  • 以修改后的形式写回数据。

Spring Batch自动执行此基本批处理迭代,提供了将一组类似的交易作为一组处理的功能,通常在脱机环境中无需任何用户交互。批处理作业是大多数IT项目的一部分,Spring Batch是唯一提供可靠的企业级解决方案的开源框架。

业务场景

  • 定期提交批处理

  • 并行批处理:作业的并行处理

  • 分阶段的企业消息驱动的处理

  • 大规模并行批处理

  • 失败后手动或计划重启

  • 顺序处理相关步骤(扩展了工作流程驱动的批次)

  • 部分处理:跳过记录(例如,回滚时)

  • 整批交易,适用于小批量或现有存储过程/脚本的情况

技术目标

  • 批处理开发人员使用Spring编程模型:专注于业务逻辑,并让框架处理基础结构。

  • 在基础结构,批处理执行环境和批处理应用程序之间明确分离关注点。

  • 提供通用的核心执行服务作为所有项目都可以实现的接口。

  • 提供可以直接使用的核心执行接口的简单和默认实现。

  • 通过在所有层中利用spring框架,轻松配置,定制和扩展服务。

  • 所有现有的核心服务应易于替换或扩展,而不会影响基础架构层。

  • 提供一个简单的部署模型,其架构JAR与使用Maven构建的应用程序完全分开。

1.3.Spring Batch 架构

Spring Batch在设计时考虑了可扩展性,并考虑了各种最终用户。下图显示了支持最终用户开发人员的可扩展性和易用性的分层体系结构。

图1.1:Spring Batch分层架构
图1. Spring Batch分层架构

这种分层的体系结构突出了三个主要的高级组件:应用程序,核心和基础结构。该应用程序包含所有批处理作业和开发人员使用Spring Batch编写的自定义代码。批处理核心包含启动和控制批处理作业所需的核心运行时类。它包括实现 JobLauncherJobStepApplication和Core都建立在通用基础架构之上。此基础结构包含通用的读写器和服务(例如RetryTemplate),应用程序开发人员(例如ItemReader和的读写器ItemWriter)和核心框架本身(重试,它是自己的库)都使用它们。

1.4.通用批处理原则和准则

构建批处理解决方案时,应考虑以下关键原则,准则和一般注意事项。

  • 请记住,批处理体系结构通常会影响在线体系结构,反之亦然。在可能的情况下,请使用通用的构建块同时考虑架构和环境进行设计。

  • 尽可能简化并避免在单个批处理应用程序中构建复杂的逻辑结构。

  • 将数据的处理和存储在物理上保持紧密联系(换句话说,将数据保存在发生处理的地方)。

  • 最小化系统资源的使用,尤其是I / O。在内存中执行尽可能多的操作。

  • 查看应用程序I / O(分析SQL语句)以确保避免不必要的物理I / O。特别是,需要寻找以下四个常见缺陷:

    • 当可以一次读取数据并将其缓存或保存在工作存储器中时,为每个事务读取数据。

    • 重新读取事务的数据,其中早先在同一事务中读取了数据。

    • 导致不必要的表或索引扫描。

    • 没有在SQL语句的WHERE子句中指定键值。

  • 不要在批处理中两次执行操作。例如,如果出于报告目的需要数据汇总,则应该(如果可能)在最初处理数据时增加存储的总数,因此报告应用程序不必重新处理相同的数据。

  • 在批处理应用程序开始时分配足够的内存,以避免在此过程中耗时的重新分配。

  • 关于数据完整性,请始终假设最坏的情况。插入足够的检查并记录验证以维护数据完整性。

  • 实施校验和以进行内部验证。例如,平面文件应具有预告片记录,以告知文件中的记录总数以及关键字段的集合。

  • 在具有实际数据量的类似生产的环境中,尽早计划和执行压力测试。

  • 在大型批处理系统中,备份可能会很困难,尤其是如果系统以24-7的方式在线联机运行时。在线设计中通常会很好地照顾数据库备份,但是文件备份也应同样重要。如果系统依赖平面文件,则不仅应建立文件备份程序并形成文件,还应进行定期测试。

1.5.批处理策略

为了帮助设计和实现批处理系统,应以示例结构图和代码外壳的形式向设计人员和程序员提供基本的批处理应用程序构建模块和模式。在开始设计批处理作业时,应将业务逻辑分解为一系列步骤,这些步骤可以使用以下标准构件来实现:

  • 转换应用程序:对于由外部系统提供或生成的每种文件类型,必须创建一个转换应用程序,以将提供的交易记录转换为处理所需的标准格式。这种批处理应用程序可以部分或全部由翻译实用程序模块组成(请参阅基本批处理服务)。

  • 验证应用程序:验证应用程序可确保所有输入/输出记录正确且一致。验证通常基于文件头和尾标,校验和和验证算法以及记录级别的交叉检查。

  • 提取应用程序:一种应用程序,它从数据库或输入文件中读取一组记录,根据预定义的规则选择记录,然后将记录写入输出文件中。

  • 提取/更新应用程序:一种应用程序,它从数据库或输入文件中读取记录,并根据每个输入记录中找到的数据来驱动对数据库或输出文件的更改。

  • 处理和更新应用程序:对提取或验证应用程序中的输入事务执行处理的应用程序。该处理通常涉及读取数据库以获得处理所需的数据,可能会更新数据库并创建记录以进行输出处理。

  • 输出/格式应用程序:读取输入文件,根据标准格式从该记录重组数据并生成输出文件以打印或传输到另一个程序或系统的应用程序。

此外,应为无法使用前面提到的构建块构建的业务逻辑提供基本的应用程序外壳。

除主要构建块外,每个应用程序还可以使用一个或多个标准实用程序步骤,例如:

  • 排序:一种程序,该程序读取输入文件并生成输出文件,其中已根据记录中的排序关键字字段对记录进行了重新排序。排序通常由标准系统实用程序执行。

  • 拆分:一种程序,该程序读取一个输入文件,并根据字段值将每个记录写入几个输出文件之一。拆分可以由参数驱动的标准系统实用程序定制或执行。

  • 合并:一种程序,可从多个输入文件中读取记录,并使用输入文件中的合并数据生成一个输出文件。可以通过参数驱动的标准系统实用程序来定制或执行合并。

批处理应用程序还可以按其输入源进行分类:

  • 数据库驱动的应用程序由从数据库检索的行或值驱动。

  • 文件驱动的应用程序由从文件中检索的记录或值驱动。

  • 消息驱动的应用程序由从消息队列检索的消息驱动。

任何批处理系统的基础都是处理策略。影响策略选择的因素包括:估计的批处理系统数量,与在线系统或其他批处理系统的并发性,可用的批处理窗口。(请注意,随着越来越多的企业希望24x7全天候运行,清晰的批处理窗口正在消失)。

批处理的典型处理选项是(按实现复杂度的升序排列):

  • 脱机模式下批处理窗口中的正常处理。

  • 并发批处理或联机处理。

  • 同时并行处理许多不同的批处理运行或作业。

  • 分区(在同一时间处理同一作业的许多实例)。

  • 前述选项的组合。

商业调度程序可能会支持其中一些或全部选项。

下一节将更详细地讨论这些处理选项。重要的是要注意,根据经验,批处理过程采用的提交和锁定策略取决于所执行的处理类型,并且在线锁定策略也应使用相同的原理。因此,在设计总体架构时,批处理架构不能只是简单的事后思考。

锁定策略可以是仅使用普通数据库锁定,也可以在体系结构中实施其他自定义锁定服务。锁定服务将跟踪数据库锁定(例如,通过将必要的信息存储在专用的db表中),并向请求db操作的应用程序授予或拒绝权限。此体系结构也可以实现重试逻辑,以避免在锁定情况下中止批处理作业。

1.批处理窗口中的常规处理对于在单独的批处理窗口中运行的简单批处理过程,在线用户或其他批处理过程不需要更新数据,并发不是问题,可以在站点上进行一次提交。批处理运行结束。

在大多数情况下,更健壮的方法更为合适。请记住,批处理系统在复杂性和处理的数据量方面都有随时间增长的趋势。如果没有锁定策略,并且系统仍依赖单个提交点,则修改批处理程序可能会很麻烦。因此,即使使用最简单的批处理系统,也要考虑对重新启动-恢复选项的提交逻辑的需求,以及有关本节稍后部分介绍的更复杂情况的信息。

2.并行批处理或联机处理可以由联机用户同时更新的批处理应用程序处理数据时,不应锁定联机用户可能需要超过200天的任何数据(数据库或文件中的数据)。几秒钟。另外,每隔几笔交易结束时,更新应提交给数据库。这样可以将其他进程不可用的数据部分和数据不可用的经过时间最小化。

最小化物理锁定的另一种选择是使用乐观锁定模式或悲观锁定模式来实现逻辑行级锁定。

  • 乐观锁定假定记录争用的可能性很小。通常,这意味着在批处理和联机处理同时使用的每个数据库表中插入一个时间戳列。当应用程序获取一行进行处理时,它还将获取时间戳。然后,当应用程序尝试更新已处理的行时,更新将使用WHERE子句中的原始时间戳。如果时间戳匹配,则更新数据和时间戳。如果时间戳不匹配,则表明另一个应用程序已在获取和更新尝试之间更新了同一行。因此,无法执行更新。

  • 悲观锁定是任何假定记录争用可能性很高的锁定策略,因此需要在检索时获得物理或逻辑锁定。一种悲观逻辑锁定使用数据库表中的专用锁定列。当应用程序检索要更新的行时,它将在锁列中设置一个标志。有了该标志,其他尝试检索同一行的应用程序在逻辑上将失败。当设置标志的应用程序更新该行时,它还会清除该标志,从而使该行可以被其他应用程序检索。请注意,在初始提取和设置标志之间还必须保持数据的完整性,例如通过使用db锁(例如SELECT FOR UPDATE)。还要注意,此方法与物理锁定具有相同的缺点,除了管理建立超时机制(如果用户在锁定记录的同时吃午饭时释放锁定)更容易管理之外。

这些模式不一定适用于批处理,但是它们可用于并发批处理和联机处理(例如在数据库不支持行级锁定的情况下)。通常,乐观锁定更适合于在线应用程序,而悲观锁定更适合于批处理应用程序。每当使用逻辑锁定时,必须对访问逻辑锁定保护的数据实体的所有应用程序使用相同的方案。

请注意,这两种解决方案都只解决锁定单个记录的问题。通常,我们可能需要锁定逻辑上相关的记录组。使用物理锁,您必须非常仔细地管理这些锁,以避免潜在的死锁。使用逻辑锁,通常最好构建一个逻辑锁管理器,该管理器了解您要保护的逻辑记录组,并可以确保锁是连贯的和非死锁的。此逻辑锁管理器通常使用自己的表进行锁管理,争用报告,超时机制和其他问题。

3.并行处理并行处理允许并行运行多个批处理运行或作业,以最大程度地减少总的批处理处理时间。只要作业不共享相同的文件,数据库表或索引空间,就没有问题。如果这样做,则应使用分区数据来实现此服务。另一种选择是通过使用控制表来构建用于维护相互依赖性的体系结构模块。控制表应为每个共享资源及其是否由应用程序使用而包含一行。然后,批处理体系结构或并行作业中的应用程序将从该表中检索信息,以确定它是否可以访问所需的资源。

如果数据访问没有问题,则可以通过使用其他线程进行并行处理来实现并行处理。在大型机环境中,传统上使用并行作业类,以确保所有进程有足够的CPU时间。无论如何,该解决方案必须足够强大,以确保所有正在运行的进程的时间片。

并行处理中的其他关键问题包括负载平衡和常规系统资源(例如文件,数据库缓冲池等)的可用性。还要注意,控制表本身很容易成为关键资源。

4.分区使用分区允许大型批处理应用程序的多个版本同时运行。这样做的目的是减少处理长时间批处理作业所需的时间。可以成功分区的进程是可以拆分输入文件和/或对主数据库表进行分区以允许应用程序针对不同的数据集运行的进程。

另外,必须将分区的进程设计为仅处理其分配的数据集。分区体系结构必须与数据库设计和数据库分区策略紧密联系在一起。请注意,数据库分区不一定意味着数据库的物理分区,尽管在大多数情况下这是可取的。下图说明了分区方法:

图1.2:分区过程
图2.分区过程

该架构应足够灵活,以允许动态配置分区数量。自动配置和用户控制配置均应考虑。自动配置可以基于诸如输入文件大小和输入记录数之类的参数。

4.1分区方法必须根据具体情况选择分区方法。下面的列表描述了一些可能的分区方法:

1.记录集的固定和均匀分解

这涉及将输入记录集分成偶数个部分(例如10个,其​​中每个部分恰好占整个记录集的1/10)。然后由批处理/提取应用程序的一个实例处理每个部分。

为了使用此方法,需要进行预处理以拆分记录集。拆分的结果将是一个上下限放置数,可以将其用作批处理/提取应用程序的输入,以便将其处理仅限于其部分。

预处理可能会产生很大的开销,因为它必须计算并确定记录集每个部分的界限。

2.按关键字列进行分解

这涉及通过键列(例如位置代码)分解输入记录集,并将数据从每个键分配给批处理实例。为了实现这一点,列值可以是:

  • 由分区表分配给批处理实例(在本节后面介绍)。

  • 通过一部分值(例如0000-0999、1000-1999等)分配给批处理实例。

在选项1下,添加新值意味着手动重新配置批处理/提取,以确保将新值添加到特定实例。

在选项2下,这确保通过批处理作业的实例覆盖所有值。但是,由一个实例处理的值的数量取决于列值的分布(在0000-0999范围内可能有很多位置,而在1000-1999范围内则很少)。在此选项下,数据范围的设计应考虑分区。

在这两种选择下,都无法实现记录到批处理实例的最佳均匀分配。没有动态配置所使用的批处理实例的数量。

3.按视图分解

这种方法基本上是按键列拆分的,但是在数据库级别。它涉及将记录集分解为视图。批处理应用程序的每个实例在处理过程中都会使用这些视图。分解是通过对数据进行分组来完成的。

使用此选项,必须将批处理应用程序的每个实例配置为命中特定视图(而不是主表)。同样,随着新数据值的添加,该新数据组必须包含在视图中。没有动态配置功能,因为实例数量的更改会导致视图的更改。

4.增加加工指标

这涉及在输入表中添加新列,该列用作指示符。作为预处理步骤,所有指标都标记为未处理。在批处理应用程序的记录获取阶段,将以该记录被标记为未处理的条件来读取记录,并且一旦读取(带锁)它们便被标记为正在处理。该记录完成后,指示符将更新为完成或错误。批处理应用程序的许多实例无需更改即可启动,因为附加列可确保记录仅被处理一次。按照“完成时,指标被标记为完成”的顺序排列一两句话。)

使用此选项,表上的I / O会动态增加。在更新批处理应用程序的情况下,由于必须进行写操作,因此减少了这种影响。

5.将表提取到平面文件

这涉及将表提取到文件中。然后可以将此文件分为多个段,并用作批处理实例的输入。

使用此选项,将表提取到文件中并将其拆分的额外开销可能会抵消多分区的影响。通过更改文件分割脚本可以实现动态配置。

6.哈希列的使用

该方案涉及在用于检索驱动程序记录的数据库表中添加哈希列(键/索引)。该哈希列具有指示符,用于确定批处理应用程序的哪个实例处理该特定行。例如,如果要启动三个批处理实例,则指示符“ A”标记为要由实例1处理的行,指示符“ B”标记为要按实例2处理的行,指示符为“ C” '标记一行以供实例3处理。

然后,用于检索记录的过程将具有一个附加WHERE子句,以选择由特定指示符标记的所有行。该表中的插入内容将涉及添加标记字段,该字段默认为实例之一(例如“ A”)。

一个简单的批处理应用程序将用于更新指标,例如在不同实例之间重新分配负载。添加足够多的新行后,可以运行该批处理(除批处理窗口外,随时可以)将新行重新分配给其他实例。

批处理应用程序的其他实例仅需要运行如前几段所述的批处理应用程序,即可重新分配指示符以与新数量的实例一起使用。

4.2数据库和应用程序设计原则

支持使用键列方法针对分区数据库表运行的多分区应用程序的体系结构应包括用于存储分区参数的中央分区存储库。这提供了灵活性并确保了可维护性。该存储库通常由一个表(称为分区表)组成。

分区表中存储的信息是静态的,通常应由DBA维护。该表应包含多分区应用程序每个分区的一行信息。该表应包含“程序ID代码”,“分区号”(分区的逻辑ID),此分区的db键列的“低”值和此分区的db键列的“高”列。

在程序启动时,id应将程序和分区号从体系结构(特别是从“控制处理任务”)传递给应用程序。如果使用键列方法,则这些变量用于读取分区表,以确定应用程序要处理的数据范围。此外,在整个处理过程中必须使用分区号,以便:

  • 添加到输出文件/数据库更新中以使合并过程正常运行。

  • 将正常处理报告给批处理日志,并将任何错误报告给体系结构错误处理程序。

4.3最小化死锁

当应用程序并行运行或分区时,数据库资源中的争用和死锁可能发生。至关重要的是,数据库设计团队应尽可能消除潜在的争用情况,这是数据库设计的一部分。

而且,开发人员必须确保在设计数据库索引表时要牢记防止死锁和性能。

死锁或热点通常发生在管理表或体系结构表中,例如日志表,控制表和锁定表。还应考虑这些含义。实际的压力测试对于确定体系结构中的可能瓶颈至关重要。

为了最大程度地减少冲突对数据的影响,体系结构应在连接到数据库或遇到死锁时提供诸如重试间隔等服务。这意味着内置机制可以对某些数据库返回码做出反应,而不是发出立即错误,而是等待预定时间并重试数据库操作。

4.4参数传递和验证

分区体系结构对于应用程序开发人员应该相对透明。该体系结构应执行与在分区模式下运行应用程序相关的所有任务,包括:

  • 在应用程序启动之前检索分区参数。

  • 在应用程序启动之前验证分区参数。

  • 在启动时将参数传递给应用程序。

验证应包括检查以确保:

  • 该应用程序具有足够的分区来覆盖整个数据范围。

  • 分区之间没有间隙。

如果数据库已分区,则可能需要进行一些其他验证,以确保单个分区不会跨越数据库分区。

同样,该体系结构应考虑分区的合并。关键问题包括:

  • 在进入下一个作业步骤之前,是否必须完成所有分区?

  • 如果其中一个分区中止会怎样?

2. Spring Batch 4.2的新增功能

Spring Batch 4.2增加了以下功能:

2.1.千分尺的批次指标

此版本引入了一项新功能,使您可以使用测微计来监视批处理作业。默认情况下,Spring Batch收集指标(例如作业持续时间,步骤持续时间,项目读写吞吐量等),并在spring.batch前缀下的Micrometer全局指标注册表中注册它们这些度量可以发送到 Micrometer支持的任何监视系统

有关此功能的更多详细信息,请参阅“ 监视和指标”一章。

2.2.Apache Kafka项目读取器/写入器

这个版本增加了一个新的KafkaItemReaderKafkaItemWriter读取数据并将其写入Kafka主题。有关这些新组件的更多详细信息,请参考Javadoc

2.3.Apache Avro项目读取器/写入器

此版本增加了一个新功能AvroItemReaderAvroItemWriter可以从Avro资源中读取数据并将其写入其中。有关这些新组件的更多详细信息,请参考Javadoc

2.4.文档更新

参考文档已更新,以匹配与其他Spring项目相同的样式。

3.批处理的域语言

对于任何经验丰富的批处理设计师而言,Spring Batch中使用的批处理的总体概念应该是熟悉且舒适的。有“工作”和“步骤”,并要求开发人员提供处理单元ItemReaderItemWriter但是,由于存在Spring模式,操作,模板,回调和惯用语,因此有以下机会:

  • 遵守关注点明显分开的情况得到了显着改善。

  • 清晰地描述了作为接口提供的体系结构层和服务。

  • 简单和默认的实现方式,可以快速采用,开箱即用。

  • 显着增强的可扩展性。

下图是已使用了数十年的批处理参考体系结构的简化版本。它概述了组成批处理域语言的组件。该体系结构框架是一个蓝图,已经在最后几代平台(COBOL / Mainframe,C / Unix,现在是Java /任何地方)上数十年的实现中得到了证明。JCL和COBOL开发人员可能会像C,C#和Java开发人员一样熟悉这些概念。Spring Batch提供了层,组件和技术服务的物理实现,这些层,组件和技术服务通常在健壮,可维护的系统中找到,这些系统用于解决从简单到复杂的批处理应用程序的创建,其基础结构和扩展可以满足非常复杂的处理需求。

图2.1:批处理原型
图3.批处理原型

上图突出显示了构成Spring Batch领域语言的关键概念。作业有一个到多个步骤,每个步骤都只有一个ItemReader,一个ItemProcessor和一个步骤ItemWriter需要启动一个作业(带有 JobLauncher),并且需要存储有关当前正在运行的进程的元数据(位于中 JobRepository)。

3.1.Job

本节描述与批处理作业的概念有关的构造型。A Job是封装整个批处理过程的实体。与其他Spring项目一样,a Job与XML配置文件或基于Java的配置连接在一起。该配置可以被称为“作业配置”。但是, Job这只是整个层次结构的顶部,如下图所示:

工作层次
图4.作业层次结构

在Spring Batch中,a Job只是Step实例的容器它组合了逻辑上属于流程的多个步骤,并允许配置所有步骤全局的属性,例如可重新启动性。作业配置包含:

  • 作业的简单名称。

  • Step实例的定义和顺序

  • 作业是否可重新启动。

Spring Batch以SimpleJob的形式提供Job接口的默认简单实现,该实现在之上创建了一些标准功能Job使用基于Java的配置时,可使用一组构建器来实例化a Job,如以下示例所示:

@Bean
public Job footballJob() {
    return this.jobBuilderFactory.get("footballJob")
                     .start(playerLoad())
                     .next(gameLoad())
                     .next(playerSummarization())
                     .end()
                     .build();
}

3.1.1.JobInstance

A JobInstance是指逻辑作业运行的概念。考虑一个应该在一天结束时运行一次的批处理作业,例如Job上图中的“ EndOfDay” 有一个“ EndOfDay”作业,但是Job必须单独跟踪每个运行在这项工作中,JobInstance每天只有一个逻辑例如,有1月1日运行,1月2日运行,依此类推。如果1月1日运行第一次失败并在第二天再次运行,则仍是1月1日运行。(通常,这也与它正在处理的数据相对应,这意味着1月1日运行处理1月1日的数据)。因此,每个都JobInstance可以有多个执行(JobExecution本章稍后将详细讨论),并且只有一个JobInstance与特定内容相对应JobJobParameters可以在给定时间运行。

a的定义JobInstance绝对与要加载的数据无关。完全取决于ItemReader实现来确定如何加载数据。例如,在EndOfDay方案中,数据上可能有一列指示该数据所属的“生效日期”或“计划日期”。因此,1月1日的运行将仅加载第1次的数据,而1月2日的运行将仅使用第2次的数据。由于此确定可能是一项业务决策,因此由 ItemReader决定。但是,使用同一个参数JobInstance可以确定是否使用ExecutionContext先前执行中的“状态”(即本章稍后讨论的)。使用新的JobInstance 表示“从头开始”,而使用现有实例通常表示“从上次中断的地方开始”。

3.1.2.作业参数

在讨论JobInstance了它与Job的不同之处之后,自然要问的问题是:“一个人JobInstance与另一个人有什么区别?” 答案是: JobParameters一个JobParameters对象拥有一组用于启动批处理作业的参数。它们可以在运行期间用于标识甚至用作参考数据,如下图所示:

工作参数
图5.作业参数

在前面的示例中,有两个实例,一个实例是1月1日,另一个实例是1月2日,实际上只有一个实例,Job但是它有两个JobParameter对象:一个对象的作业参数为01-01-2017,另一个为对象它以01-02-2017参数开始。因此,合同可以定义为:JobInstance= Job +标识JobParameters这使开发人员可以有效地控制a JobInstance的定义方式,因为他们可以控制传入的参数。

并非所有作业参数都需要有助于识别 JobInstance默认情况下,它们会这样做。但是,该框架还允许提交Job带有对a 的身份无贡献的参数的a JobInstance

3.1.3.工作执行

A JobExecution是指一次尝试运行Job的技术概念。执行可能以失败或成功结束,但是JobInstance与给定执行相对应的执行除非成功完成,否则不视为完成。Job前面所述的EndOfDay 为例,考虑JobInstance2017年1月1日的首次运行失败。如果使用与第一次运行(01-01-2017)相同的标识作业参数再次运行,JobExecution则会创建一个新的。但是,仍然只有一个JobInstance

A Job定义什么是作业及其执行方式,a JobInstance是将执行组合在一起的纯粹的组织对象,主要是为了启用正确的重新启动语义。JobExecution但是,A 是运行期间实际发生情况的主要存储机制,它包含许多必须控制和持久化的属性,如下表所示:

表1. JobExecution属性

属性

定义

状态

BatchStatus对象,指示执行的状态。在运行时,它是 BatchStatus#STARTED如果失败,则为BatchStatus#FAILED如果成功完成,那就是BatchStatus#COMPLETED

开始时间

一个java.util.Date代表当执行开始时的当前系统时间。如果作业尚未开始,则此字段为空。

时间结束

一个java.util.Date代表当执行完成后,无论它是否是成功的当前系统时间。如果作业尚未完成,则该字段为空。

退出状态

ExitStatus,说明运行的结果。这是最重要的,因为它包含返回给调用方的退出代码。有关更多详细信息,请参见第5章。如果作业尚未完成,则该字段为空。

createTime

java.util.Date表示当当前系统时间JobExecution最早持续。作业可能尚未启动(因此没有启动时间),但是它始终具有createTime,这是管理作业级别的框架所需的 ExecutionContexts

最近更新时间

java.util.Date代表上一次JobExecution持续存在的A。如果作业尚未开始,则此字段为空。

executionContext

“属性包”包含两次执行之间需要保留的所有用户数据。

failureExceptions

执行Job。时遇到的异常列表如果在失败时遇到多个异常,这些功能将非常有用Job

这些属性很重要,因为它们可以持久保存并且可以用来完全确定执行状态。例如,如果01-01的EndOfDay作业在9:00 PM执行而在9:30失败,则在批处理元数据表中进行以下输入:

表2. BATCH_JOB_INSTANCE

JOB_INST_ID

JOB_NAME

1

EndOfDayJob

表3. BATCH_JOB_EXECUTION_PARAMS

JOB_EXECUTION_ID

TYPE_CD

KEY_NAME

DATE_VAL

识别

1

日期

schedule.Date

2017-01-01

真正

表4. BATCH_JOB_EXECUTION

JOB_EXEC_ID

JOB_INST_ID

开始时间

时间结束

状态

1

1

2017-01-01 21:00

2017-01-01 21:30

失败

为了清楚和格式化,列名可能已被缩写或删除。

现在工作失败了,假设确定问题已花费了一整夜,因此“批处理窗口”现在关闭了。进一步假设该窗口在9:00 PM开始,则该作业将在01-01再次开始,从停止的地方开始,并在9:30成功完成。因为现在是第二天,所以也必须运行01-02作业,此作业随后才在9:31开始,并在正常的一小时时间内在10:30完成。并不需要一个接一个JobInstance地启动,除非两个作业有可能尝试访问相同的数据,从而导致在数据库级别锁定的问题。完全由调度程序确定何时Job应运行a。由于它们是分开的JobInstances,Spring Batch不会尝试阻止它们同时运行。(尝试JobInstance在另一个已经运行的情况下运行相同的结果 JobExecutionAlreadyRunningException会抛出该错误)。现在,JobInstanceJobParameters中都应该有一个额外的条目,并且表中应该有两个额外的条目, JobExecution如下表所示:

表5. BATCH_JOB_INSTANCE

JOB_INST_ID

JOB_NAME

1

EndOfDayJob

2

EndOfDayJob

表6. BATCH_JOB_EXECUTION_PARAMS

JOB_EXECUTION_ID

TYPE_CD

KEY_NAME

DATE_VAL

识别

1

日期

schedule.Date

2017-01-01 00:00:00

真正

2

日期

schedule.Date

2017-01-01 00:00:00

真正

3

日期

schedule.Date

2017-01-02 00:00:00

真正

表7. BATCH_JOB_EXECUTION

JOB_EXEC_ID

JOB_INST_ID

开始时间

时间结束

状态

1

1

2017-01-01 21:00

2017-01-01 21:30

失败

2

1

2017-01-02 21:00

2017-01-02 21:30

已完成

3

2

2017-01-02 21:31

2017-01-02 22:29

已完成

为了清楚和格式化,列名可能已被缩写或删除。

3.2.

A Step是一个域对象,封装了批处理作业的一个独立的顺序阶段。因此,每个工作完全由一个或多个步骤组成。一个Step包含了所有的定义和控制实际的批量处理所需的信息。这是一个模糊的描述,因为任何给定的内容Step都是由开发人员决定编写的JobA Step可以根据开发人员的需求简单或复杂。一个简单的方法Step可能会将文件中的数据加载到数据库中,几乎不需要代码(取决于所使用的实现)。较复杂的 Step业务规则可能包含复杂的业务规则,这些规则将在处理过程中应用。与a一样Job,a Step有一个个体StepExecution与unique相关联 JobExecution,如下图所示:

图2.1:带步骤的作业层次结构
图6.带步骤的作业层次结构

3.2.1.步骤执行

A StepExecution代表执行的单次尝试StepStepExecution 每次Step运行a都会创建一个新内容,类似于JobExecution但是,如果某个步骤由于执行失败而无法执行,则不会继续执行。A StepExecution仅在其Step实际启动时创建

Step执行由StepExecution的对象表示每个执行都包含对其相应步骤和JobExecution与事务相关的数据的引用,例如提交和回滚计数以及开始和结束时间。此外,每个步骤执行都包含一个ExecutionContext,其中包含开发人员在批处理运行中需要保留的所有数据,例如重新启动所需的统计信息或状态信息。下表列出了的属性StepExecution

表8. StepExecution属性

属性

定义

状态

BatchStatus对象,指示执行的状态。在运行时,状态为BatchStatus.STARTED如果失败,则状态为BatchStatus.FAILED如果成功完成,则状态为BatchStatus.COMPLETED

开始时间

一个java.util.Date代表当执行开始时的当前系统时间。如果步骤尚未开始,则此字段为空。

时间结束

一个java.util.Date代表当执行完成后,无论它是否是成功的当前系统时间。如果步骤尚未退出,则此字段为空。

退出状态

ExitStatus指示执行的结果。这是最重要的,因为它包含返回给调用方的退出代码。有关更多详细信息,请参见第5章。如果作业尚未退出,则此字段为空。

executionContext

“属性包”包含两次执行之间需要保留的所有用户数据。

读取计数

已成功读取的项目数。

writeCount

已成功写入的项目数。

commitCount

为此执行已提交的事务数。

rollbackCount

由所控制的业务交易Step已回滚的次数。

readSkipCount

read失败次数导致项目被跳过。

processSkipCount

process失败次数导致项目被跳过。

filterCount

已被“过滤”的项目数ItemProcessor

writeSkipCount

write失败次数导致项目被跳过。

3.3.执行上下文

An ExecutionContext表示键/值对的集合,这些键/值对由框架进行持久化和控制,以便允许开发人员放置一个存储范围为StepExecution对象或JobExecution对象的持久状态的位置对于熟悉Quartz的人来说,它与JobDataMap非常相似。最佳用法示例是促进重新启动。以平面文件输入为例,在处理单独的行时,框架会定期保留ExecutionContext提交点。这样做可以ItemReader在运行期间发生致命错误或断电的情况下存储其状态。所需要做的就是将当前读取的行数放入上下文中,如下面的示例所示,框架将完成其余工作:

executionContext.putLong(getKey(LINES_READ_COUNT), reader.getPosition());

JobStereotypes部分的EndOfDay示例为例,假设有一个步骤“ loadData”将文件加载到数据库中。第一次失败运行后,元数据表将类似于以下示例:

表9. BATCH_JOB_INSTANCE

JOB_INST_ID

JOB_NAME

1

EndOfDayJob

表10. BATCH_JOB_EXECUTION_PARAMS

JOB_INST_ID

TYPE_CD

KEY_NAME

DATE_VAL

1

日期

schedule.Date

2017-01-01

表11. BATCH_JOB_EXECUTION

JOB_EXEC_ID

JOB_INST_ID

开始时间

时间结束

状态

1

1

2017-01-01 21:00

2017-01-01 21:30

失败

表12. BATCH_STEP_EXECUTION

STEP_EXEC_ID

JOB_EXEC_ID

STEP_NAME

开始时间

时间结束

状态

1

1

loadData

2017-01-01 21:00

2017-01-01 21:30

失败

表13. BATCH_STEP_EXECUTION_CONTEXT

STEP_EXEC_ID

SHORT_CONTEXT

1

{piece.count = 40321}

在上述情况下,Step运行了30分钟并处理了40321个“件”,在这种情况下,这代表了文件中的行。此值会在框架每次提交之前更新,并且可以包含与中的条目相对应的多行 ExecutionContext在提交之前被通知需要各种 StepListener实现之一(或ItemStream),本指南后面将对此进行详细讨论。与前面的示例一样,假定Job于第二天重新启动。重新启动后,ExecutionContext将从数据库中重新构建上次运行的值ItemReader被打开时,它可以检查以查看它是否具有在上下文任何存储的状态,并从那里初始化自身,如图以下示例:

if (executionContext.containsKey(getKey(LINES_READ_COUNT))) {
    log.debug("Initializing for restart. Restart data is: " + executionContext);

    long lineCount = executionContext.getLong(getKey(LINES_READ_COUNT));

    LineReader reader = getReader();

    Object record = "";
    while (reader.getPosition() < lineCount && record != null) {
        record = readLine();
    }
}

在这种情况下,运行上述代码后,当前行为40322,从而允许Step 再次从中断处开始。ExecutionContext也可用于那些需要被保留的关于运行本身的统计数据。例如,如果一个平面文件包含跨多行存在的处理订单,则可能有必要存储已处理的订单数量(与读取的行数有很大不同),以便可以通过以下方式发送电子邮件:结束Step于正文中处理的订单总数。框架会为开发人员处理存储的内容,以便将其正确地分配给个人JobInstance很难知道是否存在ExecutionContext是否应该使用。例如,使用上面的“ EndOfDay”示例,当01-01运行再次第二次开始时,框架会识别出相同JobInstance并且是单独的Step,将其ExecutionContext拉出数据库,并将其移交给数据库(作为自身的一部分 StepExecutionStep相反,对于01-02运行,框架识别出它是一个不同的实例,因此必须将空上下文传递给 Step框架为开发人员做出了许多类型的确定,以确保在正确的时间将状态提供给开发人员。同样重要的是要注意,在任何给定时间都ExecutionContext存在一个StepExecution客户ExecutionContext应该小心,因为这会创建一个共享的键空间。因此,在输入值时应注意确保没有数据被覆盖。但是,Step存储绝对不会在上下文中存储任何数据,因此没有办法对框架产生不利影响。

同样重要的是要注意,至少有一个ExecutionContextJobExecution一个用于每一个StepExecution例如,考虑以下代码片段:

ExecutionContext ecStep = stepExecution.getExecutionContext();
ExecutionContext ecJob = jobExecution.getExecutionContext();
//ecStep does not equal ecJob

如评论中所述,ecStep不等于ecJob他们是两个不同的人 ExecutionContexts范围为的Step一个保存在中的每个提交点 Step,而范围为的一个保存在每次Step执行之间

3.4.JobRepository

JobRepository是上述所有构造型的持久性机制。它提供了CRUD操作JobLauncherJob以及Step实现。Job第一次启动,一个JobExecution被从库中获得,并且,执行的过程中,StepExecutionJobExecution实施方式是通过将它们传递到存储库持续。

使用Java配置时,@EnableBatchProcessing注释提供了a JobRepository作为开箱即用自动配置的组件之一。

3.5.JobLauncher

JobLauncher代表一个简单的界面,用于Job使用的给定集合 启动JobParameters,如以下示例所示:

public interface JobLauncher {

public JobExecution run(Job job, JobParameters jobParameters)
            throws JobExecutionAlreadyRunningException, JobRestartException,
                   JobInstanceAlreadyCompleteException, JobParametersInvalidException;
}

预计实现获得有效JobExecution距离 JobRepository和执行Job

3.6.物品阅读器

ItemReader是一种抽象,表示一次检索一项的输入StepItemReader用尽了它可以提供的物品时,它通过返回来表明这一点null有关ItemReader接口及其各种实现的更多详细信息,请参见 读者和作家

3.7.项目作家

ItemWriter是一个抽象,一次代表一个Step,一批或大块项目的输出通常,一个ItemWriter人不知道接下来应该接收的输入,并且只知道当前调用中传递的项目。有关ItemWriter接口及其各种实现的更多详细信息,请参见 读者和作家

3.8.项目处理器

ItemProcessor是表示项目的业务处理的抽象。ItemReader读取一项并将其ItemWriter写入的同时,它们 ItemProcessor提供了一个访问点来转换或应用其他业务处理。如果在处理项目时确定该项目无效,则返回 null指示不应将该项目写出。有关该ItemProcessor接口的更多详细信息,请 参见 读者和作家

4.配置和运行作业

在“ 领域”部分中,使用下图作为指南讨论了总体体系结构设计:

图2.1:批处理原型
图7.批处理原型

尽管Job对象看起来像是简单的步骤容器,但开发人员必须知道许多配置选项。此外,对于如何Job运行a 及其在运行期间如何存储其元数据,有许多考虑因素本章将解释.NET的各种配置选项和运行时问题Job

4.1.配置作业

Job接口有多种实现,但是构建器可以消除配置上的差异。

@Bean
public Job footballJob() {
    return this.jobBuilderFactory.get("footballJob")
                     .start(playerLoad())
                     .next(gameLoad())
                     .next(playerSummarization())
                     .end()
                     .build();
}

Job(并且典型地任何Step在其内)需要一个JobRepository的配置JobRepository通过进行处理BatchConfigurer

上面的示例说明了Job由三个Step实例组成的与工作相关的构建器还可以包含有助于并行化(Split),声明性流控制(Decision)和流定义的外部化()的其他元素Flow

4.1.1.可重启性

执行批处理作业时的一个关键问题与Job重新启动时的行为有关的启动 Job被认为是一个“重新启动”,如果 JobExecution已经存在特定的 JobInstance理想情况下,所有作业都应该能够从中断的地方开始,但是在某些情况下这是不可能的。开发人员完全有责任确保JobInstance在这种情况下创建一个新文件但是,Spring Batch确实提供了一些帮助。如果a Job绝不应该重新启动,而应始终作为new的一部分运行JobInstance,则可重新启动属性可以设置为'false':

Java配置
@Bean
public Job footballJob() {
    return this.jobBuilderFactory.get("footballJob")
                     .preventRestart()
                     ...
                     .build();
}

换句话说,将restartable设置为false意味着“这 Job不支持再次启动”。重新启动Job无法重新启动的JobRestartException,将引发:

Job job = new SimpleJob();
job.setRestartable(false);

JobParameters jobParameters = new JobParameters();

JobExecution firstExecution = jobRepository.createJobExecution(job, jobParameters);
jobRepository.saveOrUpdate(firstExecution);

try {
    jobRepository.createJobExecution(job, jobParameters);
    fail();
}
catch (JobRestartException e) {
    // expected
}

此JUnit代码片段显示了尝试JobExecution为不可重新启动的作业首次创建 不会造成任何问题。但是,第二次尝试将抛出JobRestartException

4.1.2.拦截作业执行

在执行作业的过程中,通知其生命周期中的各种事件可能很有用,以便可以执行自定义代码。SimpleJob允许通过调用一个 JobListener在适当的时候:

public interface JobExecutionListener {

    void beforeJob(JobExecution jobExecution);

    void afterJob(JobExecution jobExecution);

}

JobListeners可以SimpleJob通过作业上的listeners元素添加到中

Java配置
@Bean
public Job footballJob() {
    return this.jobBuilderFactory.get("footballJob")
                     .listener(sampleListener())
                     ...
                     .build();
}

应该注意的是,afterJob无论作业成功与否都会调用。如果需要确定成功或失败,可以从以下位置获得JobExecution

public void afterJob(JobExecution jobExecution){
    if( jobExecution.getStatus() == BatchStatus.COMPLETED ){
        //job success
    }
    else if(jobExecution.getStatus() == BatchStatus.FAILED){
        //job failure
    }
}

与此接口对应的注释为:

  • @BeforeJob

  • @AfterJob

4.1.4.JobParametersValidator

在XML名称空间中声明的作业或使用的任何子类 AbstractJob可以选择在运行时声明作业参数的验证器。例如,当您需要断言一个作业使用其所有必填参数启动时,此功能很有用。有一个 DefaultJobParametersValidator可用于约束简单的强制性和可选参数的组合,对于更复杂的约束,您可以自己实现接口。

通过Java构建器支持验证器的配置,例如:

@Bean
public Job job1() {
    return this.jobBuilderFactory.get("job1")
                     .validator(parametersValidator())
                     ...
                     .build();
}

4.2.Java配置

除了XML,Spring 3还提供了通过Java配置应用程序的功能。从Spring Batch 2.2.0开始,可以使用相同的Java配置来配置批处理作业。基于Java的配置有两个组件:@EnableBatchProcessing批注和两个构建器。

这些@EnableBatchProcessing作品与Spring系列中的其他@ Enable *注释相似。在这种情况下, @EnableBatchProcessing提供用于构建批处理作业的基本配置。在此基本配置中,StepScope除了提供许多可自动装配的bean之外还创建了的实例

  • JobRepository -bean名称“ jobRepository”

  • JobLauncher -豆子名称“ jobLauncher”

  • JobRegistry -bean名称“ jobRegistry”

  • PlatformTransactionManager -Bean名称“ transactionManager”

  • JobBuilderFactory -bean名称“ jobBuilders”

  • StepBuilderFactory -bean名称“ stepBuilders”

此配置的核心接口是BatchConfigurer默认实现提供了上述的Bean,并且需要DataSource在上下文中将作为Bean。JobRepository将使用此数据源。您可以通过创建BatchConfigurer接口的自定义实现来自定义这些bean中的任何一个通常,扩展DefaultBatchConfigurer(如果BatchConfigurer未找到a时提供 )并覆盖所需的吸气剂就足够了。但是,可能需要从头实施自己的方法。以下示例显示如何提供自定义事务管理器:

@Bean
public BatchConfigurer batchConfigurer() {
	return new DefaultBatchConfigurer() {
		@Override
		public PlatformTransactionManager getTransactionManager() {
			return new MyTransactionManager();
		}
	};
}

只有一个配置类需要具有 @EnableBatchProcessing注释。在为课程加上注释后,您将可以使用上述所有内容。

使用基本配置后,用户可以使用提供的构建器工厂来配置作业。以下是通过JobBuilderFactory配置的两步作业的示例 StepBuilderFactory

@Configuration
@EnableBatchProcessing
@Import(DataSourceConfiguration.class)
public class AppConfig {

    @Autowired
    private JobBuilderFactory jobs;

    @Autowired
    private StepBuilderFactory steps;

    @Bean
    public Job job(@Qualifier("step1") Step step1, @Qualifier("step2") Step step2) {
        return jobs.get("myJob").start(step1).next(step2).build();
    }

    @Bean
    protected Step step1(ItemReader<Person> reader,
                         ItemProcessor<Person, Person> processor,
                         ItemWriter<Person> writer) {
        return steps.get("step1")
            .<Person, Person> chunk(10)
            .reader(reader)
            .processor(processor)
            .writer(writer)
            .build();
    }

    @Bean
    protected Step step2(Tasklet tasklet) {
        return steps.get("step2")
            .tasklet(tasklet)
            .build();
    }
}

4.3.配置JobRepository

使用时@EnableBatchProcessingJobRepository开箱即用为您提供a 本节介绍配置您自己的内容。

如前所述,JobRepository用于Spring Batch中各种持久化域对象(例如JobExecution和)的 基本CRUD操作 StepExecution它是由许多主要的框架功能要求,如JobLauncherJobStep

使用Java配置时,JobRepository会为您提供a 如果提供了a,DataSource则直接提供Map基于JDBC的JDBC 否则不提供基于JDBC的JDBC 但是,您可以JobRepository通过BatchConfigurer接口的实现来自定义通道的 配置。

Java配置
...
// This would reside in your BatchConfigurer implementation
@Override
protected JobRepository createJobRepository() throws Exception {
    JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
    factory.setDataSource(dataSource);
    factory.setTransactionManager(transactionManager);
    factory.setIsolationLevelForCreate("ISOLATION_SERIALIZABLE");
    factory.setTablePrefix("BATCH_");
    factory.setMaxVarCharLength(1000);
    return factory.getObject();
}
...

除了dataSource和transactionManager外,不需要上面列出的配置选项。如果未设置,将使用上面显示的默认值。出于意识目的,它们在上面显示。varchar的最大长度默认为2500,这是示例架构脚本中VARCHAR的长度

4.3.1.JobRepository的事务配置

如果使用名称空间或提供的名称空间FactoryBean,则将在存储库周围自动创建事务建议。这是为了确保批元数据(包括故障后重新启动所必需的状态)得以正确保存。如果存储库方法不是事务性的,则框架的行为无法很好地定义。create*方法属性中的隔离级别是分别指定的,以确保启动作业时,如果两个进程试图同时启动同一作业,则只有一个成功。该方法的默认隔离级别为SERIALIZABLE,这非常激进:READ_COMMITTED也可以工作;如果两个进程不太可能以这种方式冲突,则READ_UNCOMMITTED会很好。但是,由于 create*该方法很短,只要数据库平台支持,SERIALIZED就不会引起问题。但是,可以重写:

Java配置
// This would reside in your BatchConfigurer implementation
@Override
protected JobRepository createJobRepository() throws Exception {
    JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
    factory.setDataSource(dataSource);
    factory.setTransactionManager(transactionManager);
    factory.setIsolationLevelForCreate("ISOLATION_REPEATABLE_READ");
    return factory.getObject();
}

如果不使用名称空间或工厂Bean,那么使用AOP配置存储库的事务行为也很重要:

Java配置
@Bean
public TransactionProxyFactoryBean baseProxy() {
	TransactionProxyFactoryBean transactionProxyFactoryBean = new TransactionProxyFactoryBean();
	Properties transactionAttributes = new Properties();
	transactionAttributes.setProperty("*", "PROPAGATION_REQUIRED");
	transactionProxyFactoryBean.setTransactionAttributes(transactionAttributes);
	transactionProxyFactoryBean.setTarget(jobRepository());
	transactionProxyFactoryBean.setTransactionManager(transactionManager());
	return transactionProxyFactoryBean;
}

4.3.2.更改表前缀

的另一个可修改属性 JobRepository是元数据表的表前缀。默认情况下,它们都以BATCH_开头。BATCH_JOB_EXECUTION和BATCH_STEP_EXECUTION是两个示例。但是,存在修改此前缀的潜在原因。如果需要在表名之前添加模式名称,或者在同一模式中需要一组以上的元数据表,则需要更改表前缀:

Java配置
// This would reside in your BatchConfigurer implementation
@Override
protected JobRepository createJobRepository() throws Exception {
    JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
    factory.setDataSource(dataSource);
    factory.setTransactionManager(transactionManager);
    factory.setTablePrefix("SYSTEM.TEST_");
    return factory.getObject();
}

鉴于以上更改,对元数据表的每个查询都将以“ SYSTEM.TEST_”为前缀。BATCH_JOB_EXECUTION将被称为SYSTEM.TEST_JOB_EXECUTION。

仅表前缀是可配置的。表名和列名不是。

4.3.3.内存中的存储库

在某些情况下,您可能不想将域对象持久保存到数据库中。原因之一可能是速度。在每个提交点存储域对象会花费额外的时间。另一个原因可能是您不需要为特定工作保留状态。因此,Spring批处理提供了作业存储库的内存Map版本:

Java配置
// This would reside in your BatchConfigurer implementation
@Override
protected JobRepository createJobRepository() throws Exception {
    MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean();
    factory.setTransactionManager(transactionManager);
    return factory.getObject();
}

请注意,内存中的存储库是易失性的,因此不允许在JVM实例之间重新启动。它还不能保证两个具有相同参数的作业实例同时启动,并且不适合在多线程Job或本地分区中使用Step因此,只要需要这些功能,就可以使用存储库的数据库版本。

但是,它确实需要定义事务管理器,因为存储库中存在回滚语义,并且由于业务逻辑可能仍是事务性的(例如RDBMS访问)。出于测试目的,许多人发现它 ResourcelessTransactionManager很有用。

4.3.4.存储库中的非标准数据库类型

如果使用的数据库平台不在受支持的平台列表中,并且SQL变量足够接近,则可以使用一种受支持的类型。为此,您可以使用raw JobRepositoryFactoryBean而不是名称空间快捷方式,并使用它来将数据库类型设置为最接近的匹配项:

Java配置
// This would reside in your BatchConfigurer implementation
@Override
protected JobRepository createJobRepository() throws Exception {
    JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
    factory.setDataSource(dataSource);
    factory.setDatabaseType("db2");
    factory.setTransactionManager(transactionManager);
    return factory.getObject();
}

如果未指定JobRepositoryFactoryBeanDataSource则会尝试从中自动检测数据库类型。)平台之间的主要差异主要是由增加主键的策略来解决的,因此通常可能也需要重写主键 incrementerFactory(使用一个Spring框架中的标准实现)。

如果甚至不起作用,或者您没有使用RDBMS,那么唯一的选择可能是实现DaoSimpleJobRepository依赖的各种接口,并以正常的Spring方式手动将其连接起来。

4.4.配置JobLauncher

使用时@EnableBatchProcessingJobRegistry开箱即用为您提供a 本节介绍配置您自己的内容。

JobLauncher接口的最基本实现 SimpleJobLauncher它唯一需要的依赖项是JobRepository,以获得执行:

Java配置
...
// This would reside in your BatchConfigurer implementation
@Override
protected JobLauncher createJobLauncher() throws Exception {
	SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
	jobLauncher.setJobRepository(jobRepository);
	jobLauncher.afterPropertiesSet();
	return jobLauncher;
}
...

一旦获得JobExecution,它将被传递给Job的execute方法,最终将其返回 JobExecution给调用者:

作业启动器序列
图8. Job Launcher序列

该序列很简单,从调度程序启动时效果很好。但是,尝试从HTTP请求启动时会出现问题。在这种情况下,启动需要异步完成,以便SimpleJobLauncher立即返回到其调用方。这是因为在长时间运行的进程(例如批处理)所需的时间内保持HTTP请求打开的时间不是一种好习惯。下面是一个示例序列:

异步作业启动器序列
图9.异步作业启动器序列

SimpleJobLauncher可以很容易地配置为允许这种情况下通过配置 TaskExecutor

Java配置
@Bean
public JobLauncher jobLauncher() {
	SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
	jobLauncher.setJobRepository(jobRepository());
	jobLauncher.setTaskExecutor(new SimpleAsyncTaskExecutor());
	jobLauncher.afterPropertiesSet();
	return jobLauncher;
}

spring TaskExecutor 接口的任何实现都可以用来控制如何异步执行作业。

4.5.运行工作

至少,启动批处理作业需要两件事: Job要启动的和 JobLauncher两者都可以包含在相同或不同的上下文中。例如,如果从命令行启动作业,则将为每个Job实例化一个新的JVM,因此每个作业都有自己的JobLauncher但是,如果从范围内的Web容器中运行 HttpRequest,通常将JobLauncher配置一个 ,用于异步作业启动,多个请求将被调用以启动其作业。

4.5.1.从命令行运行作业

对于希望从企业计划程序运行其作业的用户,命令行是主要界面。这是因为大多数调度程序(除非是Quartz,除非使用NativeJob除外)都直接与操作系统进程配合使用,而这些进程主要是从Shell脚本开始的。除了Shell脚本(例如Perl,Ruby)甚至“构建工具”(例如ant或maven)之外,还有许多启动Java进程的方法。但是,由于大多数人都熟悉Shell脚本,因此本示例将重点介绍它们。

CommandLineJobRunner

因为启动作业的脚本必须启动Java虚拟机,所以需要一个具有main方法的类作为主要入口点。Spring Batch提供了一个实现此目的的实现: CommandLineJobRunner重要的是要注意,这只是引导应用程序的一种方法,但是有许多方法可以启动Java进程,并且绝对不应将此类视为权威。CommandLineJobRunner 执行四项任务:

  • 加载适当的 ApplicationContext

  • 将命令行参数解析为 JobParameters

  • 根据参数找到合适的工作

  • 使用JobLauncher应用程序上下文中提供的启动工作。

所有这些任务仅使用传入的参数即可完成。以下是必填参数:

表14. CommandLineJobRunner参数

jobPath

将用于创建XML文件的XML文件的位置ApplicationContext该文件应包含运行完整作业所需的所有内容

jobName

要运行的作业的名称。

这些参数必须首先以路径传递,然后以名称传递。这些之后的所有参数都被认为是 JobParameters并且必须采用'name = value'的格式:

<bash$ java CommandLineJobRunner io.spring.EndOfDayJobConfiguration endOfDay schedule.date(date)=2007/05/05

在大多数情况下,您可能想使用清单在jar中声明您的主类,但为简单起见,直接使用了该类。此示例使用domainLanguageOfBatch中的相同“ EndOfDay”示例第一个参数是“ io.spring.EndOfDayJobConfiguration”,它是包含Job的配置类的完全限定类名。第二个参数'endOfDay'表示作业名称。最后一个参数'schedule.date(date)= 2007/05/05'将转换为JobParameters。以下是Java配置的示例:

@Configuration
@EnableBatchProcessing
public class EndOfDayJobConfiguration {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    public Job endOfDay() {
        return this.jobBuilderFactory.get("endOfDay")
    				.start(step1())
    				.build();
    }

    @Bean
    public Step step1() {
        return this.stepBuilderFactory.get("step1")
    				.tasklet((contribution, chunkContext) -> null)
    				.build();
    }
}

此示例过于简单,因为通常在Spring Batch中运行批处理作业还有更多要求,但是它可以显示CommandLineJobRunnerJob的两个主要要求。 JobLauncher

退出码

从命令行启动批处理作业时,通常使用企业计划程序。大多数调度程序都非常笨,只能在流程级别上工作。这意味着他们只知道他们正在调用的某些操作系统进程,例如shell脚本。在这种情况下,将作业成功或失败返回给调度程序的唯一方法是通过返回码。返回码是由进程返回到调度程序的数字,指示运行结果。在最简单的情况下:0是成功,1是失败。但是,可能会有更复杂的情况:如果作业A返回4个启动作业B,并且如果作业5返回5个启动作业C。这种类型的行为是在调度程序级别配置的,但重要的是,诸如Spring Batch之类的处理框架必须提供一种方法来返回特定批处理作业的“退出代码”的数字表示形式。在Spring Batch中,它封装在ExitStatus,这将在第5章中更详细地介绍。为了讨论退出代码,要知道的唯一重要的事情是,它 ExitStatus具有退出代码属性,该属性由框架(或开发人员)设置,并作为一部分返回。从 JobExecution退回的款项 JobLauncherCommandLineJobRunner转换此字符串值使用了一些ExitCodeMapper 接口:

public interface ExitCodeMapper {

    public int intValue(String exitCode);

}

an的基本约定 ExitCodeMapper是,给定字符串退出代码,将返回数字表示形式。作业运行程序使用的默认实现是,SimpleJvmExitCodeMapper 它返回0表示完成,返回1表示一般错误,返回2表示任何作业运行程序错误,例如无法Job在提供的上下文中找到 如果需要比上述3个值更复杂的东西,则ExitCodeMapper必须提供接口的自定义实现由于the CommandLineJobRunner是创建的类,ApplicationContext因此无法“连接在一起”,因此必须自动连接任何需要覆盖的值。这意味着,如果 ExitCodeMapperBeanFactory,它将在创建上下文后注入到运行器中。提供您自己的所有操作, ExitCodeMapper就是将实现声明为根级Bean,并确保它是运行ApplicationContext程序加载的Bean的一部分

4.5.2.从Web容器中运行作业

从历史上看,如上所述,已从命令行启动了诸如批处理作业之类的脱机处理。但是,在许多情况下,从中启动HttpRequest是更好的选择。许多此类用例包括报告,临时作业运行和Web应用程序支持。因为按定义,批处理作业可以长期运行,所以最重要的问题是确保异步启动该作业:

Web容器中的异步作业启动器序列
图10. Web容器中的异步作业启动器序列

在这种情况下,控制器是Spring MVC控制器。关于Spring MVC的更多信息可以在这里找到:https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc控制器Job使用 JobLauncher已配置为异步启动的来启动 ,然后立即返回JobExecutionJob可能仍在运行,但是,这种无阻塞行为允许控制器立即返回,该处理的时候需要HttpRequest下面是一个示例:

@Controller
public class JobLauncherController {

    @Autowired
    JobLauncher jobLauncher;

    @Autowired
    Job job;

    @RequestMapping("/jobLauncher.html")
    public void handle() throws Exception{
        jobLauncher.run(job, new JobParameters());
    }
}

4.6.高级元数据使用

到目前为止,已经讨论JobLauncherJobRepository接口。它们一起代表了作业的简单启动和批处理域对象的基本CRUD操作:

工作库
图11.作业存储库

A JobLauncher使用 JobRepository创建新 JobExecution对象并运行它们。 Job并且Step以后的实现会JobRepository在Job运行期间将相同的内容用于相同执行的基本更新。基本操作足以满足简单的场景,但是在具有成百上千个批处理作业和复杂的调度要求的大型批处理环境中,需要对元数据进行更高级的访问:

作业存储库高级
图12.高级作业存储库访问

JobExplorerJobOperator接口,这将在下面讨论的,用于查询和控制元数据添加附加功能。

4.6.1.查询存储库

在使用任何高级功能之前,最基本的需求是Svera: iwit;">。Jobe*JobRepository创建新 JobExecutioneiction">表14. CommandLineJob: 50%;">

可能仍在运行駱个请求将被调用以启动其作业。

inh 4.6.高级inh 到目"part>使用 JobLauncher

返回多 赖in class in a jar, but for simplicity, the class was used directly. This example is using the same 'EndOfDay' example from the ApplicationContext因此无法“连接在一起”,因此必须自动连作业5返回5个启动作业C。这种/font>

t style=-align: i .html提供一种方法来返回特定批处理作业的“退出代码”的数字表示形式。从Web容器中运行作业
提供一种方法来返回特定批处理作业的“退出代码”的数字表示形式。从Web容器中运行作业 请求-align: ialign: inherit;">,这将在第5章中更详细地介绍。为了讨论退出代码 example of the XML configuration is below:

图11.作业存储库
fra4> uctu11.out of }ode>JobLauncher: inherit;">ode>JobL作业启动器序列"> nt>ode>JobLtitle"> J(nhe J-name">beans:bean;">ode>JobLtitle"> t style=( t style=-name">beans:bean;">ode>JobLtitle"> 换此字符串值-name">beans:bean;">ode>JobLtitle">请求( 请求 ;">ode>JobL
: 50%;"> admonihor notcessing

                        
筘tylt     了表      ="lis不要忘记参rit;">浏览器t进行     ="hljs-keyword">void 
() throws Exception{&e     jobLauncher.run(job, new JobParameters());<论的Incrpan>&e    }
}
t><论的Incrpan>&e

n> /api//fon/l请/动和批);
<
}
rtical-aligContent"https:///api//fon/l请/动和批);

}
找到更详细ont> 明 工作库 code>

值自峨意ertical-align: inherit;">。

ationnt>prk-reference/web.html#mvc
code>

不过">prk-reference/web.html#mvc
n>nt>@Controller <论的$理域对象的基本CRUD操作:

象来触发ical-align: inherit;">。Jo象

="v该

<论的Incrpan>&e Job<理域对象的基本CRUD操作:

nt><理域对象的基本CRUD操作:

le="
图11.作业存储库
bLauncher jobLauncher;js-key 任何必要值来返回worhopjjp”面讨论的o象ework-reference/web.html#mvc <论的$理域对象的基本CRUD操作:

其进行worhopjjp” ical-align: inherit;">。 code>) <论的Jobojifprk-reference/web.html#mvc 所示
图11.作业存储库
style="vertical-align: inherit;">业启动器序列"> ="h论的Builverti.addfontgn: inherit;"> }CommandLineJob: 50%;">

<区分@Controller < 用 JobLauncher

<论的Jobpublle="ver定@Controller <Jobplign: publl获自嗧int>退出码&e an cbLauncher jobLauncher; <&e 'bLauncher jobLauncher;<器ibute }ApplicationContext<从Web容器中作业5返回5个启动作业C。这footballt><-align: inherit;">从Web容器中incrpan>&e &e gument, ndex-single t stmg src="img/la;">,这将j>< font>

&e Job 与woyword”nhe联="img/job-repository.png" alt="工作库"> class in a jar, but for simplicity, the class was used directly.

图11.作业存储库
.incrpan>&e (sa>&e 使 . stmg src="img/l span> throws Exception{<- jobLauncher.run(job, new JobParameters());<- } }
it;">

启动odee crit;" <和批处理域对象的基本CRUD操作:

正used directly. href="index-siD操: it> 无t>图11.作业存储> 由tfont stylfootballt><-align: ) .incrpan>&e (sa>&e 使 . stmg t><论的Incrpan>&e
到曐域对象的基本CRUD操作: 所示
图11.作业存 ode>JobL作业启动器序列"> nt><-align: ) ode>JobLtitle"> J(nhe J-name"Llign<-aInst11. nt>get<-aInst11.se">beans:bean;">ode>JobLtitle">请求( /font>ode>Joont st styleun.id-align: e="vertican;">ode>Jocount J(nhe J-name"理作业的 nt>get<-a作业的j>>beans:bean;">ode>JobLtitle">Lo( 业的Id J(nhe J-name": in作业的 nt>get: in作业的j>>beans:bean;">ode>JobLtitle">Lo( j-a作业的Id, Lo( s in作业的Id J(nhe J-name"<-aInst11. nt>get<-aInst11.j>>beans:bean;">ode>JobLtitle">Lo( inst11.Id J(nhe J-name"Llign<-a作业的 nt>get<-a作业的se">beans:bean;">ode>JobLtitle"><-aInst11. j-aInst11. J(nhe J-name":elign<-a作业的 nt>f R 作业的se">beans:bean;">ode>JobLtitle">请求( /font>< }
style="vertical-align: inherit;"><;">"hle="vertic签名n: inhererit出nherit;">从Web容器中运行tfont stylfootballt><-align: ) .incrpan>&e (sa>&e 使 . stmg inher读版ed ;">从Web容器中运行tfont stylfootballt><-aow:

font>
ass=;">从Web容器中运行tfont stylfootballt><-aow:

font>
所示 它们一起仦的问题是确动和批处codep> 理域对象的基本CRUD操作:

JobRepository图11.作业存储库对象并运vertical-align: inherit;">
le=" D操作:A 从p> er ojifpt>JobOperatorJobOperator业启动器序列"> ="h } style="vertical-align: inherit;"> w:

T"verPde>ix bLauncher jobLauncher;js-key 任何必要值来返回worhopjjp”面讨批章fontfont stylfootbference/web.html#mvc
< 用 ow:

font>
<-align: )
.incrpan>&e (sa>&e 使 . stmg "conten了作
所示 它们一起仦的问题是确动和批处codep> 理域对象的基本CRUD操作:

JobRepository图11.作业存储库ix"vertic 对象并运vertical-align: inherit;">
le=" D操作:A 从p> er ojifpt>JobOperatorJobOperator业启动器序列"> ="h ixcher: inherit;"> } style="vertical-align: inherit;">new JobParameters());<- } ignreg"> it;">

启动odee crit;" <和批处理域对象的基本CRUD操作:

ml#mvc 用 owg">

<论的ignce:, but foocdiv: 50%;"> ).htmlcal-制 word">但> 想跟踪哪eritle="vert>hmgntelign: n: i: ittent"Job<行咄基子e class="hil)> 很: itte
图11.作业存

所示 它们一起仦的问题回,该处理的时候需要Ht域对象的基本CRUD操作:

JobRepository图11.作业存储库JobExecution<>JobRepositortyle="verMapJgnowg">nt style="vertical-align: inherit;">对象并运vertical-align: inherit;">图11.作业obRepositortyle="verMapJgnowg">nt style="vertical-align: inherit;">对象并运vertical-aligntd cla由: inherit;">回c写简单启> JobRepositorynt style="vertical-align: inherit;">对象并运vertical-alignv clas根foo: inherit;"> inh求简单 杂aunch-from-req
nt style="vertical-align: inherit;">对象并运vertical-alignv c C。t stylfoo:载di..ylfoo:域="pa几乎 3个o/di 决">图11.作业存储库 erMapJgnowg">nt style="vertical-align: inherit;">对象并运vertical-align><和规/font> > st> .adtyle杂简><和规/fo行程图错误,例如无法nt style="vertical-align: inherit;">对象并运vertical-alignv13.gn: ) 例如无法c<和惽力>3象的基本CRUD操作:它们一起仦的问n: i: itte操/font> rti.ad“面向>ode定<和风格it;">图11.作业存储库ode><和托指halign读 allt><-ylfoo: 事边界-a写t de宜>定RUD操作:

ml#mvc 甎读 an> ItemReiv class="title"> ItemWriody> nt>f R 作业的se">beans:bean;">ode>JobLtitle">请求( /fonfootbferebl事aunch-from-req
"对象的基本CRUD操作: ="h nt style="vertical-align: inherit;">对象并运vertical-alignv14.>c<和惽力> <论的$理域对象的基本CRUD操作:它们一起仦的问ssljdo/di "对象的基本CRUD操作:A Array" ();ow:

fonal-align:f"工作庺讨论退出代码 ="
pan> <论的$理域对象的基本CRUD操作:Job< 了作版示形nfont <;bll获自嗧int>< er定@C;">对象尽管a处hede>"ver 较ode>JobRepositor erMapJgnowg">nt style="vertical-align: inherit;">对象并运vertical-alignical-a它> mallt><-rc="杂简类n>&e ode>JobL作业启动器序列"> nt><-align: ) ode>JobLtitle"> J(nhe J-name"Llign<-aInIn er to easl-a示形nafont sstyln: i: itteneun.id-alfollowi:ex stylign: e="vertican;">ode>Jocount J(nhe J-name"理作业的 nt>get<-ack j>>beans:bean;XML C示形nafontCRUD操作:

nt>get<-a作业的j>>beans:bean;">ode>JobLtitle">Lo( 业的Id J(nhe J-name": in作业的 nt>get: in作业的j>>beans:bean;">ode>JobLtitle">Lo( jt stylOragrinhcod nt>get: in作业的j>>> -r/tica.getObs:bean;">ode>JobLtitle">Lo( j
                 srMapJ        nt>get: in作业的j>>beans:bean;">ode>JobLtitle">Lo( jtrMa1js-keyword">throws Exception{&e     jtaskletpJ        nt>get: in作业的j>>transa基-manaununch-from-req	           itle">     transa基Manaunufont>
}
找到iv clah-from-req itle"> itemReiv cgrinhcod nt>get: in作业的j>>wriody> h-from-req itle"> itemWriody器t进行 ="hljs-keyword"aliit-iit;"val> h-from-req itle"> 10器takljdgm_doc" href="index-single.html#advancedMetaData"> code> J(nhe J-name"Llign<-a作业的 nt>get<-a作业的se">beans:bean;">ode>JobLtitle"><-aInst11. j-aInst11. rti.adJ的wsa><;50%;">v clasrti.adn: i: ittet>< 行sljdJob<-align: )
ck ag">nt style="vertical-align: inherit;">对象并运vertical-alignJ的wsa><;力> <论的$理
.incrpan>&e (sa>&e 使
. stmg inher读版ed ;">从Web容器中运行tfont-align: inheri* Notesstylont>

is typ并ly autowired st andl sr neegn: to 11.explick yri* 示形ncd ati器中运行tfont stylfootballt><-aow:

font>
<-ao
象来触
所示 font.wriody(itemWriody> 所示 font.它们一起仦的问题是确动和批处codep> 理域对象的基本CRUD操作: /auncher: inherit;">表14. CommandLineJob: 50%;"> 面 inhsa><;包括 面向he目he,例如无法Job<理域对象

por wriody> nt>f R 作业的se">beans:bean;">ode>JobLtitle">请求( /fonfo/font> nt>f R 作业的se">beans:bean;">ode>JobLtitle">请求( /fon><和批 <理域对象 J(nhe J-name"理作业的 ul J-name"Llign<-aInCRUD操作:

por transa基-manaununc :ln: i’s">ode>JPlatformTransa基Manaunutitle">that 11gins andl"aliitsCRUD操作:

>>>>transa基s dnfon pD操作.g/jon: inherit;"t><理域对象<-align: ) &e 'bL

por transa基Manaunu> nt>f R 作业的se">beans:bean;">ode>JobLtitle">请求( /fonfo/n: i nt>f R 作业的se">beans:bean;">ode>JobLtitle">请求( /fon>躔it styl> st> bl事aunch-from-<理域对象 J(nhe J-name"理作业的 ul J-name"Llign<-aInCRUD操作:

por > -r/tica.getOb :lTrit;

>>>>;i .le

>>>>( define:bean;st al//la> akljd), it is rtde>Joont ot styl//la> akljd e . For a hrdal䜬CRUD操作:

>>>>srMa, it is define:bas rtde>Joont of styl//lataskletakljd.g/jon: inherit;"t><理域对象<-align: ) &e 'bL

por r/tica.getOb nt>f R 作业的se">beans:bean;">ode>JobLtitle">请求( /fonfo/font>ode>JobLtitle">请求( /fon>> }
style="vertic定期t>JobRepositor erMa例如无法
Job<理域对象 J(nhe J-name"理作业的 ul J-name"Llign<-aInCRUD操作:

por "aliit-iit;"val> :lTriters()) of iodmslto 11.pD操ed 11forelstyltransa基 isCRUD操作:

>>>>"aliitted.g/jon: inherit;"t><理域对象<-align: ) &e 'bL

por hunk } nt>f R 作业的se">beans:bean;">ode>JobLtitle">请求( /fonfo/"ver

m基于he目<理域对象ode>JobLtitle"> J(nhe J-name"Llign<-aInIt should 11l srcdthat r > -r/tica.getOb defaultslto r > ;/tica.getObject andCRUD操作:r transa基-manaununc defaultslto r transa基Manununc . Also,herit;i Item isCRUD操作:op基al, celstyliodmlcould 11ldirectly paed fromlstylreiv clto stylwriody.g/jon: inherit;"t><理埽业的 nt>get<-a作业的se">beans:bean;">ode>JobLtitle"><-aInst11. j-aInst11. 应当.png" f R 作业的se">beans:bean;">ode>JobLtitle">请求( /fon默 例如无法< > ;/tica.getObject font>Jobbeans:bean;">ode>JobLtitle">请求( /fonCRUD操作:默 例如无法< transa基Manununc nt>f R 作业的se">beans:bean;">ode>JobLtitle">请求( /fonfoame":eis础 fromlstylreG: ) ode>JobLtitle"> J(nhe J-name"Llign<-aInIt should 11l srcdthat 箱即i›您的Id
要jdCRfont><-align: ) &e 'bL

>>>>;i .lela> akljd), it is rtde>Joont ot styl//la> akljd e . For a hrdal䜬CRUD操作:

>>>>srMa, it is define:be:balready provd vial-aliame":eis础例cont<理域对象
<-align: ) jaunch-from-rtributio'itcrpan>&e 'bL

por r/tica.getOb nt>f Ritor erMa例如无法ode>Jol-ahopjjp="

por wriody> nt>f R 作业的se">beans:bean;">ode>JobLtitle">请求( /fonfo/font>
<-两def: ) ode>JobLtitle"> J(nhe J-name"Llign<-aInIt should 11l srcdthat
充容器d JobLt r/后<-alignrom->JobLtifault商生命周期组件值code><区分@Controller < 各节D操求( 这两def cti isCRUD操作:op基al, celstyliodmlcould 11ldirectl.incrpan>&e (sa>&e 使 何ntribut r/postp 所示 它们一起仦何ntribut r/postp J(nhe J-name"vaunch-fromPostP{<- jobLauncher.run(job, new JobParameters());<- } }< ifault JobLauncher

<理埽业的 lign-top">

beans:bean;">ode>JobLtitle">请求( /fonfo/n: i

nt>f R 作业的se">beans:bean;">ode>JobLtitle">请求( /fon>躔it styl> st> bl事aunch-from-<理域对象 J(nhe J-namnch-fromPostP st> bl事aunch-fpp }beans:bean;">ode>JobLtitle">请求( /fon默 例如无法Maeblock agmg src 税 轻obLtitle">请求(法< t /st> bl事aunch-from- nt>f Re>

>>>>( define:lign-top">

nt style="vertical-align: inherit;">对象并运vertical-align: inherit;"><-align: ) jaunch-fromPostP&e 'bLfonnch-fromPostPode>JobLtnch-fromPostPnt style="vertical-align: ine>

new JobParameters());<- } }<尽管ont>ign: e=<-alignro被赋予>&e (sa>&e 使 . stmg "conten了作

&e (sa>&e 使 automc何ntribuarit;"> 所示 它们一起仦automc何ntribuarit;itcrpacode> J(nhe J-name"odeifault new JobParameters());<- } }< jsfrom-数 divey 任这些 iv>ifault这些 ign: e : e Joo hunk } : e e>Jo系轻松e:her:然”c v> le=" D操作此 D操轻松e任何组>JojdCRnspa每phe>JojdCRn仅e:><理域对象 nt简style="vertical-align: ine> ent>>JobLt 容易 .incrpan>&e (sa>&e 使 . stmg "con><- ss="tablebloclstylreiv clto stylwriody.g/jon: inherit;"t><理埽业的 lign-top">

beans:bean;">ode>JobLtitle">请求( /fonfo/n: i

nt>f R 作业的se">beans:bean;">ode>JobLtitle">请求( /fon>躔it styl> st> bl事aunch-from-<理域al-at为止, J(nhe J-Automchopjjp="artributio法< t 行sljd st> bl事aunch-fpp }beans:bean;">ode>Ja st> bl事aunch-from-<理域al-at为止, J(nhe J-C/ufopathXml 法< t 行sljd st> bl事aunch-fpp }beans:bean;">ode>Jreso了bLtode>JobLtitle">Lo/a>职位codep class="tableblcedMetaData"> st> bl事aungn: inhe nt><理域对象从Web容器中运行tfont-align: inheri* 职位codep class="tableblcedMetaData"> nt><-align: )

>>>>srMa, it is define集&inherit;"t><理域对象ode>f R 作业的se">beans:bean;">ode>JobLtitle"集 容易 .incrpan>&efaa group Dean;">ode>span> milarnt>new a行sljd st>JobLode>f R ns:beawhichitle"nt>creteDean;">ode>span> st>ta"> /fonf"childean;">ode>f R n bnews-kesical-alio'itcrJobParameserit;"t>ode>span> 躔it styl> st> bl事aunch-from- 容易 .incrpan>&eign-ntode>ode>pan> creteS ,>ta">

请ddiutitlely,/as:bean;">CRUD操作> ittop">

creteS bean;">ode>pan> J(nhe J-name"理作业的 pD操ed 11for理域对: e=ss=块贡献: e )) of iodmslto 11.pD操ed 11forelstyltransa基 isCRUD操作:

>>>>"aliitted.g/jon: inherit;"t><理域对象请求( /fonfo/"ver

m基于he目f R 作业的se">beans:bean;">ode>JobLCRUD操作:<理域对象 -r/tica.getOb defaultslto r > ;/tica.getObject andCRUD操作:
r transa基-manaununc defaultslto r transa基Manununc . Also,herit;i Item isCRUD操作:
op基al, celstylioduld 11ldirectly paed fromlstylreiv clto stylwriody.g/jon: inherit;"t><理埚的 nt>get<-a作业的se">beans:bean;">ode>JobLl-ae>请求( /fonfo/"ver

m基于he目creteS e">请求( /fonfo/"ver

mobL<于he目f R 作业的se">beans:bean;">ode>JobLCRUD操作:<理域对象 -r/tica.getObpnhe -manaununc defaultslto r tinhe 基Manununc . Also,herit;i Item isCRUD操作:
op基al, celstylioduld 11ldirectly paed fromlstylreiv clto stylwriody.g/jon: inherit;"t><理埚的 nt>get<-a作业的se">beans:bean;">ode>JobLl itle"> 应当.png" f R 作业的se">bean集 容易 .incrpan>&PostP基clstylrbeacal-align-ntjobical-alignTh//ftwo">

J(nhe J-name"理作业ont r/oo hunk } : e e>Jo系轻松e模 cdiv> nt简style="verticalPostP基clstyl/CRUD n-nt>beac的sawhnn-pabs ode>JobLtnch-from. Irs());ssla jobLauncher.run(job,

beac/ldeLc启mojdCnt>p ct>beac/ign-ntjob, re abroccurs:e:: ) <理域对象 全局de>Joo hunk } : e e>Jo系轻松e:her:然”c v> n" beac/ign-ntf>bop">

bea:e:: ) <理域对象 h5的/foac&inherit;"t><理域对象ode>f R 5贡献: e )) of iodmsse">bean集 > 容易 .incrpan>&Sometimes,-keymay nee aryLtid">new a;obLode>f R n 使 /业Ca t>ode>f R la jobLauncher.run(job, 何ntribut ," nt>ode>f R n >/foac 很: itte

an;">/foacs = .ont>beac/ign-n bop"ibutio'itcr>ode(s rtde>s.it .next">A <献: e )) of iodmslto 11.pD操ed 11forelstyltransa基 isCRUD操作:

>>>>"aliitted.g/jon: inherit;"t><理域对象请求( /fonfo/"ver闭 stylw立即闭obLtitlfon 没易 松ont 立即闭> b别nt 理 stmgrc="nts 控t 的obLa人员代码hee集<的
ign: e=<-alignro袼la jobLauncher.run(job, <理域对象ode>f R 5aboresn:-a-j/font> )) of iodmsse">bean集 > 容易 .incrpan>&nk }times,-keymay nee aryLtid">new a;obLode>f R n 使 /业Ca t>ode>f R la jobLauncher.run(job, ifault这些 ign: e

mallt><-rcal-tballt回cal-a容rit;">-keywogrc="JobLtnch-from. Irs());ssla jobLauncher.run&e (sa> nt简style="vertin(job工作库"> code> :lTriters()) of iodmslto 11.pD操edABANDONED任这些 iv>ifault这些 ign: e <;bll获自嗧int>< er定@C;">ifault这些 ign: e b运ogrc="CR理标lass 跳 v clto 运olizssrc="ign-top@C;">ifault这些 ign: e &e 使失败运ogrc="C e > 容易 .incrpan>&S标las/p> 骤"val> :lTriters()) of iodmslto c> > 容易 .incrpan>&Sh-fro继续Maget:/a>Jobr骤ogrc="退出/font>工作库"> nt>get<-a作业的se">beans:bean;">ode>JobLl-ae> <论的$理
.incrpan>&e (sa>&e 使
.ltoMagica终ertic@C;">ode>f R n >Job{e日期cationCistitical-ahopjjp= get:手job告诉 > "tableul> :lTriters()) of iodmslto 11.pD操edFAILED任这些 iv>ifault这些 ign: e ifault这些 ign: e <决策> 自inhesrc="
> 容易 .incrpan>&nkertical-align: inhe.它们一起仦的问起仦的问起 Adminnk }仦o: e Joo hunk } : e e>Jo系nk }ti运ogrc="e=<-alignro袼la jobLauncher.run(job, ode>f R 5cstylOrag nelont> )) of iodmsse">bean集//fiodmslto 11.pD操ed nel<献: e h2&inher期ody> < jd.g/yl//latask> transa基Manaunufont> } beans:bean;">ode>Ja st> bl事领域操䫠C e <理域al-at为止, J(nhe J-C/ufopathXml讨论那样JobLtnch-from. Irs());ssla jobLauncher.runaiodmslto 11.pD操ed nel<献: encher.run(job, ode>f R n > 法< 装了 税 运tica.o独:bea顺l阶段tableblcedsljlde>Jobrt 际 税 霍作 仦息ont><;bll获自嗧int>< er it islep">JojdCRn仅e:t>beans:bean;">ode>Ja< 蟺 isCRU ign: ei ont><;bll获自嗧iwss事de;">r< .作:<;bll获自嗧irun(job, JojdCRn仅e:keymay nee aryLtid">new a;obLode>f R n 使 /业Ca t>oRn仅e: jobLauncher.run(job, ifault这些 ign: e

mallt><-rcal-tballt回cal-a容rit;">-keywogrc="JobLtnch-from 蟺 isCRUagica终ertic@C;"> code>ode>JobLl-ae> <论的$理
.incrpat styleABANDONED任这些 iv>ifault这些 ign: e b运ogrc="CR理标lass 跳 v clto 运olizssrc="ign-top@C;">ifault这些 ign: e &e 使失败运ogrc="C e > 容易 .incrpan>&S标las/p> 骤"val> :lTriters() 蟺 isCRUagica终le="vertical-ali .incrpan>&Sh-fro继续Maget:/a>ode>JobLl-ae> <论的$理 .incrpa些 iv>ifault这些 ign: e <;bll获自嗧int>< ign: e b运ogrc="CR理标lass 跳 v clto 运olizssrc="ign-topnt stylele日期cationCistitical>JojdCRnahopjjp= 得知titlfon t>bean集//fiodmsmerg<;bt>&inher期ody> < jd.g/yl//latask> beans:bean;">ode>Ja<;bll获自嗧ifoibo r<理域al-at为ed ical-tatus.STOP这些 /fon < ed < dd< dd> )) , -aIynical-.pD操 h, <;bll获自嗧ifoi )).pD操 specifiTOP迬Cnt>p ctmerge=ode> :lTriters()) of }rit/da任tatus.S<;b it/aJojdCRn仅e:t>beans:bean;">ode>Jasunk } <;bll获自嗧int>< ceymenerOne 际 . Irs(ceymenerTwoerit;"t>aJojdCRn仅e:keymay nee aryLtid">new a;obLode>f R n 使 /业Ca t>oRn仅e: jobLauncher.run(job, ifault这些 ign: e

mallt><-rcal-tballt回cal-a容rit;">-keywogrc="JobLtnch-fromceymeners isCRUagica终ertic@C;"> code>ode>JobLl-ae> <论ceymener理 .incrpafrit;">-keywogrc="JobLtnch-fromceymenerOneint>< ign: e ode>Jot>运ogrc="CR理标lass 跳 v clto 运olizssrc="ign-top@C;">ifault这些 ign: e &e 使失败运ogrc="C e > 容易 .incrpan>&S标las/p> 骤"val> :lTriters()ceymeners isCRUagica终le="vertical-ali .incrpan>&Sh-fro继续Maget:/a>ode>JobLl-ae> <论的$理 .incrpa些 iv>ifault这些 ign: e <;bll获自嗧int>< er定@C;">ifault这ersaean;">ode>f R n > code>-keywogrc="JobLtnch-fromceymenerTwoint>< ign: e ode>Jot>运ogrc="CR理标lass 跳 v clto 运olizssrc="ign-topnt stylele日期cationCistitical>JojdCRnahopjjp= 得知titlfon t>

nt>f R 'itcrpa/fo">beans:bean;">ode>JobLtitle">请求( /fon>躔it styl> st> bl事'itcrpa/fo">bg/jon: inherit;"t><理域对象<-align: ) h-fromPostP st> bl事aunch-fpp }odes. Irsse">beanlassmay e bc请-fro="tabl'," 请ddiutitlely,/as:be/font>

>>>>srMa, it is define:be:balready prov着-fro="tabl'," iody.g/jon: inherit;"tlwriody.g/jon: inherit;"tae>请ddiutitlely,/as:be1se">ly s;">ode各st>s. IrsaJobLtitlhe目JobLont r/oo 非常昂贵 R 作业的se">beans:bean;">ode>JobLtitn;"情况下作好/la>st> r/oo :尽rom-Jo in 全 应当.p } : e nt何ntribut ," nt>Jo系轻松ed csock,n;">o了bLt -fro="tabl'," s业的 nt>get<-a作业的se">beans:bean;">ode>JobLtitle"><-dc> )) of iodm);ssla job nt>get<-a作业的se">beans:bean;">ode>JobLtitle"><-d.g/yl//latasklet inhiody.g/jon: inherit;"tlwriody.g/jon: inherit;"tae>请ddiutitlely,/as:be期cationCistitical> an;">/foac对象并运vertical-align: inherit;"><-align: ) jaunch-fromPostP&e 'bLfonnch-fromPostPode>JobLtnch-fromPos erMa例如无法nt style="vertical-align: ine>

new<>ign: e=<-alignro被赋予>&e (sa>&e 使 . stmg "conten了作ifault这c何ntribuarit;"> 所示 它们一起仦automc何ntribuarit;itcrpacode> J(nhe J-name"odeifault JojdCRnspa每phe>JojdCRn仅e:><理域对象 ent>JobLtJobLauncher eAt><- ss="tablebloclstylreiv clto stylwriody.g/jon: inherit;"t><理 nt>f R 作业的se">beans:bean;">ode>JobLtitle">请求( /fon>躔it styl> st> bl事au-nt ent> st> bl事aunch-fpp } st> bl事aunch-from-<理域al-at为止, J(nhe J-C/ufopathXml 法< t 行sljd st> bl事n<和d"> st> bl事n<和d"> stributio法< t 行sljd st> bl事aunch-fpp }st> r/oo :10st>s. Irsean;">何ntribut ," nt>: e nt 易ean;">何ntribut ," nt>次a:e:: ) adla job nt>get<-a作业的se">beans:bean;">ode>JobLtitle"><-上调assme aryLtid">new a;obLode>f R n本CRUD操作:f R 到10: e /p> pos. IrsabLtit将aunche到nt>

por wriody> nt>f R 作业的se">beans:bean;">ont> < wriody> nt>f Rc new a;obL何ntribut ," nt>nt 易ean;">何ntribut ," nt>次a:e:: ) adla job nt>get<-a作业的Trano -ntle"><-上调assme aryLtid">new a;obLode>f R n本CRUD操作:<-上调assme ">何ntribut ," nt>次a:e:: ) adla job nt>get<-a作业的Trala>st> r/oo :尽rom-Jo in 全 应当.p } : e ntnew a;obL何ntribut ," nt>nt 易ean;ean;">何ntribut ," nt>Jo系轻松ed csock,n;">o了bLt -fro="tabl'," s业的 nt>get<-a作业的se">beans:bean;">ode>JobLtitle"><-dc> )) of iodm);ssla job nt>get<-a作业的se">beans:bean;">ode>JobLtitle"><-d.g/yl//latasklet inhiody.g/jon: inherit;"tlwriody.g/jon: inherit;"tae>请ddiutitlely,/as:be期cationCistitical> an;">/foac: >对象并运vertical-alrpacode>< .le 作业C。fonnch-frbeansns:bean; n;">: >rpacode><-align:beansns:bean; n;">: /foortributio'itcrprpacode>fonnch-frrpacode>JobLti(se">beans:bean;">ode>JobLti">fonnch-frrpacode>&e 使失败<-mPostP
op基al, celstyliodmlcould 11ldirectl.incrpan>&e (sa>&e 使 何ntribut r/postp 所示
它们一起仦何ntribut r/postp iv>i数-at为止,Jobele日期cationCistitical>JojdCRnahopjjp= 得知tiUD擤>ode>f R 作业的se">beans:bean;">ode>JobLtitle"集ode>f R 作业的se">beans:bean;">odeat为止, st> bl事aunch-from-<理域al-atcal-ahopjjp= 得知titlfon t>Joo hunk } : e e>Jo系轻bleblcedMetaDataert styl递增positde>Jobele日期cationCistitical>JojdCRnahopjjp= 得负责 st> bl事a o免on">Jobele日期cationCistitical>JojdCRnahopjjp= 得<- ss="t: er某些 bL o免on">ifault这些 ign: e &e 使">ode>项或AOP JobLaunch重新 eAt><- ss="tablebloclstylreiv clto stylwriody.g/jon: inherit;"t>:ljd st> bl事aunch-from-<理域al-atcal-ahopjjp= 得知titlfon t>Joo hunk } : e e>Jo系轻- }: transa基Manaunufont> } t;">ode>f R 作业的se">beans:bean;">odeat为止,oden(job,t oftitcrpaIa">JojdCRnahopjjp= 得被sle>那 .incrpafrit;">-keywogrc="Jo ">ode>mes,父div> e g 使&Som jd予想/latask>&e 使 . stmg "conten了作它们一起仦automc何ntean集
.incrpa些 iv>ifault这些 ign: e 运ogrc="CR理标lass 跳 v ">前- } transa基Manaunufont> } - J(nhe J-C/ufopathXml讨论那样JobLtnch-from. Irs());ssla jobLauncher.runaiodmslto 11.pDt;">-keywogrc="JobLtnch-fromceymeners isCRUabeans:bean;">ode>Jaifault这些 iljutio'itcrjn 员通Lbody> a;obL&Son body> 停/jon: 重新 的s> st总 nt>g 䉤 se">beans:bean;">ode>Jabean些运> J(nhe J-C集 > 容易 .incrpauncher.run(job, beans:bean;">ode>Ja b别nt 理 stmgrc="nts 控t 的obLa人员代码hee集<的
fonnch-frtical>pan> &nk }times,-keymayfro继续Maget:/a> aryLtid">new a;obLode>f R n 使 /业Ca t> bteg/jon: ihopjjpr aryLtid">new a;obLode>f R n 使 /业Ca t> aryLtid">new a;obLode>f R n 使 /业Ca t> pan> e=<-alignro袼ro继续Maget:/a> aryLtid">new a;obLode>f R n 使 /业Ca t> aryLtid">new a;obLode>f R n 使 /业Ca t>pan> e=<-alignro袼的obLaro继续Maget:/a> aryLtid">new a;obLode>f R n 使 /业Ca t> > 容易 .incrr/ aryLtid">new a;obLode>f R n 使 /业Ca t>pan> e=<-alignro袼的obLaro继续Maget:/a> aryLtid">new a;obLode>f R n 使 /业Ca t>new a;obLode>f R n 使 /业Ca t>f R n 使 /业Ca t>oRn仅e: jobLauncher.run(job, Re>ode>de>Joo hunk } : e e>Jo系轻- }Re>ode>d基Manaunufont> } <理域对象<重启2. Ia">ode>f R 作业的se">beans:bean;">odeat为止,oden(job,t oftitcrpaIa"> lilig : e e>Jo系轻- } h5的/foac&inherit;"t><理域对象 } h5的/foac&inherit;"t><理域对象<讨aunufont>&inherit;"t><理域对象<重新启动o袼的obLaro继续Maget:/aes,父div> e g 使&Som jd予想/latask>JojdC-aouC需要些特定ont>ode>f R 5贡献: e )) of iodmsse">>< 次a:被s de>Joo hunk } : e e>Jo系轻- } } new a;obL<-align:beansns:bean; n;">止,oden(job,t oftitcrpaIa">它们一起>new-aouCt望控aa缀r h5的/foac&inherit;"t><理域对象<启动l v ">前- } 如> h5的/foac&inherit;"t><理域对象< e=ss .incrpan>&inherit;"t><理域对象<某ym特定域 e=ss .incrpan>&inherit;"t><理域对象o朿某y必须<何ntean不ss=eleaouC不ss=要求 nt>g 使&Som jd予想/latask> h5的/foac&inherit;"t><理域对象 h5的/foac&inherit;"t><理域对象<-/为> h5的/foac&inherit;"t><理域对象 )) of aryLtid">newrjn 员通Lbody> a;obL&Son body> newtit">停/jon: 重新 的s> st总 nt>g 䉤 se">beans:bean;">o aryLtid">newhe缀rbean些运> J(nhe J-C集 > 容易 titlfon 没易 松ont 立即闭> b别nt 理 stmgrc="nts 控t 的obLa代码hee集<的
请ddiutitlely,/as:be1se">ly s;">ode各st>s. IrsaJobLtitlhe 控t 的obLa人员代码hee集<的
bParaml> :lTriters()) of iodmslto 11.pD操ed nel//lasrMaaonnt便轻松e其包含目数 nt>fonnch-frtical>次a:e:: ) adla job nt>get<-a作业的Trano -ntle"><-上调assme aryLtid">new a;obLode>f R n本CRUD操作:beans:bean;">o aryLtid">newnew和的obLaro继续Maget:/a> aryLtid">new a;obLode>f R n 使 /业Ca t> aryLtid">newR la jobLauncher.run(job, aryLtid">new a;obL aryLtid">new a;obLode>f R n 使 /业Ca t>pan> e=<-alignro袼的obLaro继续Maget:/a> aryLtid">new a;obLode>:/s op , NoSuchaulli<-alilign-op ,的obLa人员代NoSuf R n 使 /业Ca t>beans:bean;">o aryLtid">new a;obL<-align:beansns:bean; n;">止,oden(job,t oftitcrpaIa">ode>f R n 使 /业Ca t> code>o引发/fo < 所示 它们一起仦a er定@C;it;Manaunufont> } J(nhe ballt><-align:beansns:bean; n;">止,oden(job,t oftitcrpaIa">uC丏cat多cationCpD擧终运行>newn鮃"a><;第一l成功v ">前- } 如验证lele日> h5的/foac&inherit;"t><理域对象< arygnlass清fontoftor缀r&inherit;"t><理域对象 e g 使&Som jd予想/latask>态为“已完成”(> code>new nc=">&inherit;"t><理域对象ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t> )) of aryLtid">newrjn 员通Lbody> a;obL&Son body> newtit">停/jon: 重新 的s> st总 nt>g 䉤 se">beans:bean;">o aryLtid">newhe缀rbean些运> J(nhe J-C集 > 容易 titlfon 没易 松ont 立即闭> b别nt 理 stmgrc="nts 控t v clto 运olizssrc="ign-topnt stylele日期cationCistitical>JojdCRnahopjjp= 得知titlfon t>

nt>f R 'itcrpa/fo">beans:bean;">ode>JTriters()) of iodmslto 11.pD操ed nel//lasrMaaonnt便轻松e其包含目数 nt>fonnch-frtical> nt:e:: ) adla job nt>get<-a作业的Trano -ntle"><-上调assme aryLtid">new a;obLode>f R n本CRUD操作:beans:bean;">o aryLtid">newnew和的obLaro继续Maget:/a> aryLtid">new a;obLode>f R n 使 /业Ca t> aryLtid">newR la jobLauncher.run(job, aryLtid">new a;obL aryLtid">new a;obLode>f R n 使 /业Ca t>pan> e=<-alignro袼的obLaro继续Maget:/a> aryLtid">new a;obLode>a er定@C;op , NoSuchaullibeans:bean;">o献: e )) of iodmsse">>< 次a:a>Re>ode>E -n(Tde>Joo hunk } : e e>Jo系轻- }Re>ode>E -n(TdMl-ali: e h5的/foac&inherit;"t><理域对象< b新启动<="a>new a;obL<-align:beansns:bean; n;">止,oden(job,t oftitcrpaIa">&inhebLa显bLa如><="a><作acal-/其.runa运o新启动s=int>< ahopjjp= 得知titlfon t> )) of aryLtid">newrjn 员通Lbody> a;obL&Son body> newtit">停/jon: 重新 的s> st总 nt>g 䉤 se">beans:bean;">o aryLtid">newhe缀rbean些运> J(nhe J-C集 > 容易 .incrpauncher.run(job, ode>JTriters()) of iodms>ode>t 显知titlfon t>

> 容易 titlfon 没易 松ont 立即闭> b别nt 理 stmgrc="ntSoerloadgn-top ';">ode>JTriters()) of iod bParaml> :lTriters()) of iodmslto 11.pD操ed nel//lasrMaaonnt便SoerFileI松e其包含目数 nt>< se">beans:beaf值10/apan> &nk }times,-keymayfro继续Maget:/a> aryLtid">new a;obrmTrss=块贡献: e > 容易 titlfon 没易 松ont 立即闭> b别nt 理 stmgrc="ntg Loadgn-top ';">ode>JTriters()) of iod

bParaml> :lTriters()) of iodmslto 11.pD操ed nel//lasrMaaonnt便g FileI松e其包含目数 nt>< se">beans:beaf值10/apan> &nk }times,-keymayfro继续Maget:/a> aryLtid">new a;obrmTrss=块贡献: e > 容易 titlfon 没易 松ont 立即闭> b别nt 理 stmgrc="ntSoerSummarnherit;gn-top ' 控t 的obLa人员代码hee集<的

Jojdas:be1se">ly s;">ode各st>s. IrsaJobLtitlhe2lign-top">

bParaml> :lTriters()) of iodmslto 11.pD操ed nel//lasrMaaonnt便SoerSummarnherit;Source包含目数 nt>< se">beans:beaf值10/apan> &nk }times,-keymayfro继续Maget:/a> aryLtid">new a;ob un确l-keyworNoSuchault这些lign-top '5'">R la jobLauncher.run(job, beans:bean;">o aryLtid">newnew和的obLaro继续Maget:/a> aryLtid">new a;obLode>f e其包含目数 aryLtid">newR la jobLauncher.run(job, aryLtid">new a;obLode>f R n 使 /业Cafootba ili>ode>f R n 使 /业Ca t>pa续Maget:/a>ode>:/s(SoerLoadew a;obLode> ode> ode>un(job, 使 /业Ca 作t> aryLtid">new a;obLode>f R n 使 /业Ca t>pan> e=<-alignro袼的obLaro继续MagetSoerLoadgn-top ' a;obLod iA确ceyCotelign-top , NoSuchaulli<-alilign-top ,的obLa人员代NouchaulliSoerFileI松e其ew a;obLod"> aSoernnch-few a;obLod"f R n 使 /业Ca t>使 /业Ca 作t> aryLtid">new a;obLode>f R n 使 /业Ca t>pan> e=<-alignro袼的obLaro继续Magetg Loadgn-top ' a;obLod"a er定@C;op , NoSuchaulliod"> ag nnch-few a;obLod"f R n 使 /业Ca t>使 /业Ca 作t> aryLtid">new a;obLode>f R n 使 /业Ca t>pan> e=<-aligro袼的obLaro继续MagetSoerSummarnherit;gn-top ' a;obLod":/s op , NoSuchaulli<-alilign2n-top ' a;obLod iA确ceyCotelign-top , NoSuchaulli<-alilign-top ,的obLa人员代NouchaulliSoerSummarnherit;Sourceew a;obLod"> asummarynnch-few a;obLod"f R n 使 /业Ca t>beans:bean;">o aryLtid">new a;obL<-align:beansns:bean; n;">止,oden(job,t oftitcrpaIa">ode>f R n 使 /业Ca t>oer.run(job, oer.run(job, oncrpafrit;">-keywogrc="Jo ">ode>mes,父div> e g 使&Som jd予想/latask>oer.run(job, 耜hopjjp= eo g Load>oer.run(job, ifault这些 ign: egeeLaunche一tio会auncher.run(job, oncrpafrit;">-keywogrc="Jo ">ode>mes,父div> e JojdCR游戏w a;obaull玩家ob计信息">ode>f R n 使 /业Ca t>oer.run(job, ifault这些 ign: eCR文件de>f R n 使 /业Ca t>oer.run(job, ifault这些 ign: eroer.run(job, 前- } a始终动,“ CRnahopjjp= ”nc=""“ pan ”v ">前- } 指bLa器/l滥确保运ote"摘要ele日确 前- } < <="a><为起L限a为2.nherna何ntean馂果该tionC连续失败何䈙">o将nps=退anau码返回给控a作a行e=操-/员nspa渔.运衜C进行请勿o新obLtyleABANDONED任这些 iv>ifault这动作业C。newadmon //lasrnoC;itauncher.run(job, t tauncher.run(job, body>dtid">newicgn-tauncher.run(job, newfa icgn-noC;i obL="ont>ditauncher.run(job, dtid">newR la jobuncher.run(job, new a;obL<-align:beansns:bean; n;"::::<止,oden(job,t oftitcrpaIa">Jojd本文档obLaroh-fromceymeners isCRUabeans:bean;">ode>Jaifault这::::<">ode>f e其包含目数 a::<"tdtauncher.run(job, t tauncher.run(job, beans:bean;">o aryLtid">new a;obL<-align:beansns:bean; n;">止,oden(job,t oftitcrpaIa"> }oh-fromceymeners isCRUabeans:bean;">ode>Jaifault这些 ign: e三ca运行中oaull运行们一auncher.run(job, e gONED任这些 iv>ifault这动作业C。new a;obL<-align:beansns:bean; n;">止,oden(job,t oftitcrpaIa"> )) of aryLtid">newo>/fa;obicballt><-align:beansns:bean; n;">oltid">newa;obicballt><-align:beansns:bean; n;" n;">litauncher.run(job, oer.run(job, ifault这::litauncher.run(job, oer.run(job, ifault这::litauncher.run(job, oncrpafrit;">-keywogrc="Jo ">ode>mes,父div> e ifault这::ifault这动作业C。new a;obL<-align:beansns:bean; n;">止,oden(job,t oftitcrpaIa"> )) of aryLtid">newo>/fa;obicballt><-align:beansns:bean; n;">oltid">newa;obicballt><-align:beansns:bean; n;" n;">litauncher.run(job, oer.run(job, /ufonte" ">oden(job,t oftitcrpaIa">nentean鮃已经成功完成,pa渔>f e其包含目数 a::<"nt> } code>获nv ">前- ONED任这些 iv>ifault这::litauncher.run(job, oer.run(job, 指bLa器/l指bLa它"尚未oiA确nv ">前- ONED任这些 iv>ifault这::litauncher.run(job, oncrpafrit;">-keywogrc="Jo ">ode>mes,父div> e 指bLa器进行te"滷nnspa 30分钟e.l.败tyleABANDONED任这些 iv>ifault这::ifault这动作业C。new a;obL<-align:beansns:bean; n;">止,oden(job,t oftitcrpaIa"> )) of aryLtid">newo>/fa;obicballt><-align:beansns:bean; n;">oltid">newa;obicballt><-align:beansns:bean; n;" n;">litauncher.run(job, oer.run(job, /ufonte" ">oden(job,t oftitcrpaIa">nentean鮃已经成功完成,pa渔>f e其包含目数 a::<"nt> } code>获nv ">前- ONED任这些 iv>ifault这::litauncher.run(job, oer.run(job, 指bLa器/l指bLa它"尚未oiA确nv ">前- ONED任这些 iv>ifault这::litauncher.run(job, oncrpafrit;">-keywogrc="Jo ">ode>mes,父div> e o启动,pa渔作a立即被终止>nentean这是ob三l执行oncrpafrit;">-keywogrc="Jo ">ode>mes,父div> e oh-fromceymeners isCRUabeans:bean;">ode>Ja code><理域al-atcal-ahopjjp= 得知titlfon t> stingSkipde>Joo hunk } : e e>Jo系轻- }> stingSkipd基Manaunufont> } ode>f R 作业的se">beans:bean;">odeat为止,oden(job,t oftitcrpaIa">它们一起>neoiA确te">中遇ifault这劙> h5的/foac&inherit;"t><理域对象<失败何而跳te" .incrpa些 iv>ifault这些 ign: 通常这是必须由了解w: e 本身及crpa义s=人做出CRn定v ">前- } 如财务n: e uC法跳te"何ntean鮃">o导致资金<转移wsa>需要<;bllnbeal-aA/f n 使 /业Ca t>ne加C供商an;">oduC">o导致跳te" .incrpa些 iv>ifault这些 ign: 馂果由于格式错误或缺少必要s=信息而未oC供商何䈙uCna问题 .incrpa些 iv>ifault这些 ign: 通常wsa>些良记录也">o<记录下来何稍e.s;"au听器时lin予cal-绍beal-aA/foacode>f R 5贡献: e )) of iodmsse">作业的se">beans:bean;">odeat为止,oden(job,t oftitcrpaIa">&inhebLa显bLa了每phe跳te"限aontbLal-ahopjjp= 得知titlfon t>ifault这些 iljutio'itcrjn 员通Lbody> a;obL&Son body> 停/jon: 重新 的s> st总 nt>g 䉤 se">beans:bean;">ode>Jabean些运> J(nhe J-C集 > 容易 titlfon 没易 松ont 立即闭> b别nt 理 stmgrc="nts 控t v clto代码hee集<的

fonnch-frtical>< se">beaf值10/aJojdakip1se">ly s;">ode各st>s. IrsaJobLtitlhe 0 控t v cltock ac 旦控t 权作:s aunch-from st/fakippt -excnpe -nch-fes 控t v cltock a ac 旦控t 权作:s aunch-from st/fincludebut ," CRnspa每phe>Jojdnsply s;">ode各st>s. IrsaJobLtitlheorg.spitlfr stwork.batch.">fo.file.FlatFileParseExcnpe jbut ,"her.run&e (sa> kippt -excnpe -nch-fes 控t v cltock un确l-keyworNoSuchault这些lign-top '5'">ont>bParaml> 控t v clto代码hee集<:e:: ) adla job nt>get<-a作业的Trano -ntle"><-上调assme aryLtid">new a;obLode>f R n本CRUD操nlassljdg> bteg/jon: ihopjjpr aryLtid">new a;obLode>f R n 使 目数 nt> aryLtid">new a;obL aryLtid">new a;obLode>f R n 使 /业Ca t>pan> e=<-alignro袼的obLaro继续Maget:/a> aryLtid">new a;obLode>faultTolerantjob, ode>f R n 使 /业Ca t> > 容易 .incrr/ oer.run(job, ifault这些 ign: 馂果,>e=何时l些 iv>ifault这劙>oer.run(job, /ufonte" ">oden(job,t oftitcrpaIa">取>neoiA确>neo入)都-aouCt发声明CR常及crpa类nv 但是单独CR;obL是CRele执行n对>取>neoiA确eo入CR;te"进行CR何但是限a<于所跳te" .incrpa些 iv>ifault这些 ign: 一lb, o发异常而不是十beal-aA/foacode>f R 5贡献: e )) of iodmsse">作业的se">beans:bean;">odeat为止,oden(job,t oftitcrpaIa">ifault这劙>oer.run(job, /ufonte" ">oden(job,t oftitcrpaIa">o导致oh-fromceymeners isCRUabeans:bean;">ode>JanenheruC确CR;为 .incrpa些 iv>ifault这些 ign: 但是何st他们一起>neouC容易确定哪y异常l导致失败并跳te"t他䉀n容>ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t>ifault这些 iljutio'itcrjn 员通Lbody> a;obL&Son body> 停/jon: 重新 的s> st总 nt>g 䉤 se">beans:bean;">ode>Jabean些运> J(nhe J-C集 > 容易 titlfon 没易 松ont 立即闭> b别nt 理 stmgrc="nts 控t v clto员代码hee集<的
fonnch-frtical>< se">beaeaf值10/aJojdakip1se">ly s;">ode各st>s. IrsaJobLtitlhe 0 控t v cltock aagmc 旦控t 权作:s aunch-from st/fakippt -excnpe -nch-fes 控t v cltock a aaagmc 旦控t 权作:s aunch-from st/fincludebut ," CRnspa每phe>Jojdnsply s;">ode各st>s. IrsaJobLtitlhe .对.Excnpe jbut ,"her.run&e (sa>Jojdnsply s;">ode各st>s. IrsaJobLtitlhe .io.FileNotFoundExcnpe jbut ,"her.run&e (sa> kippt -excnpe -nch-fes 控t v cltock k un确l-keyworNoSuchault这些lign-top '5'">ont>bParaml> 控t v cltoo代码hee集<:e:: ) adla job nt>get<-a作业的Trano -ntle"><-上调assme aryLtid">new a;obLode>f R n本CRUD操nlassljdg> bteg/jon: ihopjjpr aryLtid">new a;obLode>f R n 使 目数 nt> aryLtid">new a;obL aryLtid">new a;obLode>f R n 使 /业Ca t>pan> e=<-alignro袼的obLaro继续Maget:/a> aryLtid">new a;obLode>faultTolerantjob, ode>noSkip(FileNotFoundExcnpe .Sucha a;obLode>f R n 使 /业Ca t> > 容易 .incrr/ } code>CR常类n该id">ne指bLa䉀font> }oer.run(job, g 使&Som jd予想/latask>CR常 e g iv>ifault这些 ign: 但是何通te"“排除”些 iv>ifault这劙>oncrpafrit;">-keywogrc="Jo ">ode>mes,父div> e netincute">CR常类>CRn;">o优化"o部font> }oer.ru oncrpafrit;">-keywogrc="Jo ">ode>mes,父div> e ifault这些 ign: 馂果遇CR常类C致命CR佈也就n: 它"不">o<跳te"nv ">前- ONED任这些 iv>ifaul容易 .incrr/ 定 nt>g iv>ifault这些 ign: 任何未分类>CR常l<视"“致命”.常v ">前- ONED任这些 iv>ifaul容易 .incrr/ a;obL&Son body> s doesrnoC m>Joer.这些 iv>ifaul容易 .incrr/ }oer.run(job, oer.run(job, g iv>ifault这些 ign: s=顺序eABANDtitcrpaIa">ode>f R 5贡献: e )cal-ahopjjp= 得知titlfon t>Joo hunk } : e e>Jo系轻- } } ode>f R 作业的se">beans:bean;">odeat为止,oden(job,t oftitcrpaIa">ne您希望异常l致跳te"> h5的/foac&inherit;"t><理域对象<失败tyleABANDtitcrpaIa">外C>定性的 .incrpa些 iv>ifault这些 ign: 馂果劙>oer.run(job, /ufonte" ">oden(job,t oftitcrpaIa">ifault这些 ign: a e ifault这些 ign: ">new a;obLoer.run(job, }oncrpafrit;">-keywogrc="Jo ">ode>mes,父div> e obLa当前进>已尝试更新另一ull进>已锁定oCR;o录t>请等待乶重试duC">o导致成功tyleABANDtitcrpaIa">neo按>&inhe方式="a><重试l-ahopjjp= 得知titlfon t>ifault这些 iljutio'itcrjn 员通Lbody> a;obL&Son body> bean些运> J(nhe J-C集 > 容易 titlfon 没易 松ont 立即闭> b别nt 理 stmgrc="nts 控t v clto代码hee集<的
fonnch-frtical>< se">beaf值10/aly s;">ode各st>s. IrsaJobLtitlhe3 控t v cltock ac 旦控t 权作:s aunch-from st/fgnlryt -excnpe -nch-fes 控t v cltock a ac 旦控t 权作:s aunch-from st/fincludebut ," CRnspa每phe>Jojdnsply s;">ode各st>s. IrsaJobLtitlheorg.spitlfr stwork.dao.D/lasLoserDataAccessExcnpe jbut ,"her.run&e (sa>gnlryt -excnpe -nch-fes 控t v cltock un确l-keyworNoSuchault这些lign-top '5'">ont>bParaml> 控t v clto代码hee集<:e:: ) adla job nt>get<-a作业的Trano -ntle"><-上调assme aryLtid">new a;obLode>f R n t>ifault这些 ia > bteg/jon: ihopjjpr aryLtid">new a;obL aryLtid">new a;obLode>f R n 使 /业Ca t>pan> e=<-alignro袼的obLaro继续Maget:/a>odSuchaullii松e其 Re/lasrlign-top '5'"> aryLtid">new a;obLode>faultTolerantjob, odSuchlry(D/lasLoserDataAccessExcnpe .Sucha a;obLode>f R n 使 /业Ca t> > 容易 .incrr/ h5的/foac&inherit;"t><理域对象<允许CR时间中ocaLos=限atyleABANDtitcrpaIa">请参见些 iv>ifault这劙>Jo系轻- } h5的/foac&inherit;"t><理域对象 } ode>f R 5贡献: e )cal-ahopjjp= 得知titlfon t>Joo hunk } : e e>Jo系轻- }>lrolls:bRollbackd基Manaunufont> } ode>f R 作业的se">beans:bean;">odeat为止,oden(job,t oftitcrpaIa">ne无论重试还是跳te"何都-抛出任何异常sa>些常beans:bean;">ode>Jahopjjp= eo : e h5的/foac&inherit;"t><理域对象 e CR因 .incrpa些 iv>ifault这些 ign: 馂果,前所述<="a><了 kip何䈙"抛出>CR常oer.run(job, o导致回a .incrpa些 iv>ifault这些 ign: 但是何s;">它们一起>ne"中t发>CR常beans:bean;">ode>Jaifault这些 ign: 釺于sa>ca因劙> h5的/foac&inherit;"t><理域对象<运住phe起La>CR常ln;">ol<="a><>ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t>ifault这些 iljutio'itcrjn 员通Lbody> a;obL&Son body> 停/jon: 重新 的s> st总 nt>g 䉤 se">beans:bean;">视任务he缀rbean些运> J(nhe J-C集 > 容易 titlfon 没易 松ont 立即闭> b别nt 理 stmgrc="nts 控t v clto代码hee集<的
fonnch-frtical>Jojdnsply s;">ode各st>s. IrsaJobLtitlheorg.spitlfr stwork.batch.">fo.a i理or.V i理 Excnpe jbut ,"her.run&e (sa>get<-a作业的Trano -ntle"><-上调assmno-rollback-excnpe -nch-fes 控t v clto代码hee集<:e:: ) adla job nt>get<-a作业的Trano -ntle"><-上调assme aryLtid">new a;obLode>f R n t>ifault这些 ia > bteg/jon: ihopjjpr aryLtid">new a;obLode>f R n 使 目数 nt> aryLtid">new a;obL aryLtid">new a;obLode>f R n 使 /业Ca t>pan> e=<-alignro袼的obLaro继续Maget:/a>odSuchaullii松e其 Re/lasrlign-top '5'"> aryLtid">new a;obLode>faultTolerantjob, ode>f R n 使 /业Ca t> > 容易 .incrr/ Joo hunk } : e e>Jo系轻- } } f R n 使 目数 nt><-align:beansns:bean; n;">止,oden(job,t oftitcrpaIa">CR本契约oer.run(job, g 使&Som jd予想/latask>CR们一起>ne"需要";取oo新;取Lifault这些 ign: 但是何sRy们一起>ne阅;器是建立s;如JMS队ln;之类>CR事务资源之上的 .incrpa些 iv>ifault这些 ign: C这种们一起>ne由于队ln;与回a>CR事务e=联,un(jobr"队ln;中拉出>CR消息放回处 .incrpa些 iv>ifault这些 ign: n(jobt>.运衜tionC<="a><为"缓冲Lne如>&inhebLa所bLal-ahopjjp= 得知titlfon t> 容易 .incrr/ nt> a;obL&Son body> 停/jon: 重新 的s> st总 nt>g 䉤 se">beans:bean;"> nt>bean些运> J(nhe J-C集 > 容易 titlfon 没易 松ont 立即闭> b别nt 理 stmgrc="nts 控t v clto员代码hee集<的
fonnch-frtical>beaeaf值10/a<:e:: ) adla job nt>get<-a作业的Trano -ntle"><-上调assme aryLtid">new a;obLode>f R n t> 容易 .incrr/ 容易 .incrr/ nt> aryLtid">new a;obLode>f R n 使 目数 nt> aryLtid">new a;obL aryLtid">new a;obLode>f R n 使 /业Ca t>pan> e=<-alignro袼的obLaro继续Maget:/a>odSuchaullii松e其 Re/lasrlign-top '5'"> aryLtid">new a;obLode>chaullIsTransahaullalQueuejob, 容易 .incrr/ 容易 .incrr/ 献: e )cal-ahopjjp= 得知titlfon t>Joo hunk } : e e>Jo系轻- } } ode>f R 作业的se">beans:bean;">odeat为止,oden(job,t oftitcrpaIa">oncrpafrit;">-keywogrc="Jo ">ode>mes,父div> e oncrpafrit;">-keywogrc="Jo ">ode>mes,父div> e ifault这劙>oer.run(job, netyleABANDtitcrpaIa">ne事务属性CR更多信息t>请参见些 iv>ifault这劙>Jo系轻- } h5的/foac&inherit;"t><理域对象 } beans:bean;">ode>Janeoncrpafrit;">-keywogrc="Jo ">ode>mes,父div> e oncrpafrit;">-keywogrc="Jo ">ode>mes,父div> e ifault这劙>oer.run(job, ifault这些 iljutio'itcrjn 员通Lbody> a;obL&Son body> 停/jon: 重新 的s> st总 nt>g 䉤 se">beans:bean;">视任务he缀rbean些运> J(nhe J-C集 > 容易 titlfon 没易 松ont 立即闭> b别nt 理 stmgrc="nts 控t v clto员代码hee集<的
fonnch-frtical><的
obLauncher.run(job, beaeae">beans:bean;">易 松ont 立即propagerit;>obLauncher.run(job, beaeae">beans:bean;">易 松ont 立即timeout>obLauncher.run(job, <:e:: ) adla job nt>get<-a作业的Trano -ntle"><-上调assme aryLtid">new a;obLode>f R n t>ifault这些 ia > bteg/jon: ihopjjpr aryLtid">new a;obLode>f R n 使 目数 nt> aryLtid">new a;obL aryLtid">new a;obLode>f R n 使 /业Ca t>pan> e=<-alignro袼的obLaro继续Maget:/a>odSuchaullii松e其 Re/lasrlign-top '5'"> aryLtid">new a;obLode>transahaullA eibute( eibute a;obLode>f R n 使 /业Ca t> > 容易 .incrr/吸cal-ahopjjp= 得知titlfon t>Joo hunk } : e e>Jo系轻- } } <beans:bean;">ode>Jaode>f R 作业的se">beans:bean;">odeat为止,oden(job,t oftitcrpaIa"><beans:bean;">ode>Jag 使&Som jd予想/latask><beans:bean;">ode>Ja e ifault这劙><" iher : e e>Jo系轻- } h5的/foac&inherit;"t><理域对象< } 前- titcrpaIa"><beans:bean;">ode>Ja e 前- ONED任这些 iv>ifaul容易 .incrr/ oer.run(job, oer.run(job, beans:bean;">ode>Ja }<beans:bean;">ode>Jane那么sa>些<自注冶 nt>g iv>ifault这些 ign: 任何t他䵁C需要单独注冶 nt>g iv>ifault这些 ign: st间接依赖L佈例如委托n注入 h5的/foac&inherit;"t><理域对象<通te"'sCoe>ifault这劙>&inhebLa所bLal-ahopjjp= 得知titlfon t>ifault这些 iljutio'itcrjn 员通Lbody> a;obL&Son body> 停/jon: 重新 的s> st总 nt>g 䉤 se">beans:bean;">视任务he缀rbean些运> J(nhe J-C集 > 容易 titlfon 没易 松ont 立即闭> b别nt 理 stmgrc="nts 控t v clto员代码hee集<的
<-上调assmoe><-上调assmont>bParaml> 控t v cltoo代码hee集<:e:: ) adla job nt>get<-a作业的Trano -ntle"><-上调assme aryLtid">new a;o使 /业Ca 使 /业Ca c 旦控t 权作:s aunch-from st/fbeans:b/a> b别nt 理 stmgrc="ntcomposonnch-frtical>Jojdnsply s;">ode各st>s. IrsaJobLtitlheorg.spitlfr stwork.batch.">fo.support.ComposoI>fonnch-frtical>< 控t v clto员代码hee集<的
ode各st>s. IrsaJobLtitlhedelegates<-上调assmbeans:rjn 含 控t v cltoc nt>get<-a作业的Trano -ntle"><-上调assmbeans:propticy nt>get<-a作业的Trano -ntle"><-上调assmbeans:b/a>new a;obLode>f R n t>ifault这些 ia > bteg/jon: ihopjjpr aryLtid">new a;obLode>f R n 使 目数 nt> aryLtid">new a;obL aryLtid">new a;obLode>f R n 使 /业Ca t>pan> e=<-alignro袼的obLaro继续Maget:/a>odSuchaullii松e其 Re/lasrlign-top '5'"> acomposoI>fonnch-f Re/lasrlign-top '5'"oe><(fileI松nnch-f1 Re/lasrlign-top '5'"oe><(fileI松nnch-f2 Re/lasrlign-top '5'"f R n 使 /业Ca t>使 /业Ca 使 /业Ca c 旦控t 权eeaa jo/** * In Spitl Batch 4, the ComposoI>fonnch-f implem> s I松yCoe>< so Maao isn't * necessary, but used for example. */ aryLtid">new a;obLfonnch-f aryLtid">new a;obLfonnch-f>ode>f R n 使 /业Ca t>fonnch-ftel > s => s.add(fileI松nnch-f1 Rn 使 /业Ca > s.add(fileI松nnch-f2 Rn 使 /业Ca 使 /业Ca ComposoI>fonnch-f i>fonnch-f =>fonnch-f n 使 /业Ca 使 /业Ca i>fonnch-f.setDelegates(> son 使 /业Ca 使 /业Ca job, fonnch-fn 使 /业Ca t> > 容易 .incrr/ fonnch-fbeans:bean;">ode>Ja<beans:bean;">ode>Jane"两ca托C .incrpa些 iv>ifault这些 ign: n(jobt>.须䰆两ca托编写者C确注冶ean>ne"便框架确处理它" nt>g iv>ifault这些 ign: s劙>oer.run(job, nentean它ocull直接财产hopjjp= l-ali: e h5的/foac&inherit;"t><理域对象< nt>g 使&Som jd予想/latask>CR们一起>ne读取oeo入oob态t运补确保留beal-aA/foacode>f R 5贡献: e )cal-ahopjjp= 得知titlfon t>Joo hunk } : e e>Jo系轻- } } beans:bean;">ode>Jaode>f R 作业的se">beans:bean;">odeat为止,oden(job,t oftitcrpaIa">beans:bean;">ode>JanesR行期间 nt>gtory;/tl-ali: e beans:bean;">ode>Jag iv>ifault这些 ign: 会有;">它事件nifault这些 ign: o户.uC需要R行某y功uC nt>g iv>ifault这些 ign: 例如ean了o出需要oa>CR ,文件n需要 nt>g iv>ifault这些 ign: st成后>beans:bean;">ode>Jabeans:bean;">ode>Jane"便.运编写oa nt>g 使&Som jd予想/latask>它al-aA/foacbeans:bean;">ode>Jag iv>ifault这些 ign: 之一来t成些 iv>ifault这劙>前- ONED任这些 iv>ifaul容易 .incrr/ oer.run(job, s=何所>&inhuCt现lt口身).运衜phe>oer.run(job, <>CRtio操-/劙>前- 使&Som jd予想/latask>oer.run(job, ifault这些 ign: 黺议您stphe其功uCob别声c听o何或者n如果,具有多种功uC佈例如al-aA/foacoer.run(job, oer.run(job, CR䜀细粒度b别声, nt>g iv>ifault这些 ign: inhebLa显bLaostb别应phe>CRc听oahopjjp= 得知titlfon t>ifault这些 iljutio'itcrjn 员通Lbody> a;obL&Son body> 停/jon: 重新 的s> st总 nt>g 䉤 se">beans:bean;">视任务he缀rbean些运> J(nhe J-C集 > 容易 titlfon 没易 松ont 立即闭> b别nt 理 stmgrc="nts 控t v clto员代码hee集<的
o含 控t v cltock aagmc 旦控t 权作:s aunch-from st/fl/foen>oraml> :lTriters()) of iodmsfjobLauncher.run(job, bL/foenjbut ,"her.run&e (sa><-上调assml/foens>o含 控t v cltoc代码hee集<:e:: ) adla job nt>get<-a作业的Trano -ntle"><-上调assme aryLtid">new a;obLode>f R n t>ifault这些 ia > bteg/jon: ihopjjpr aryLtid">new a;obLode>f R n 使 目数 nt> aryLtid">new a;obL aryLtid">new a;obLode>f R n 使 /业Ca t>pan> e=<-alignro袼的obLaro继续Maget:/a> awnch-f Re/lasrlign-top '5'"l/foen(ont>bL/foen Re/lasrlign-top '5'"f R n 使 /业Ca t> > 容易 .incrr/ oer.run(job, beans:bean;">ode>Jaoer.run(job, ifault这劙>oer.run(job, ne自注冶ojprbeans:bean;">ode>Jane如果住phe命名空间 nt>gtory;/tl-ali :/a>tid">ner.run(job, g 使&Som jd予想/latask> h5的/foac&inherit;"t><理域对象< nt>g 使&Som jd予想/latask>ifault这劙>Jo系轻- } h5的/foac&inherit;"t><理域对象<注冶<beans:bean;">ode>Ja } 前- ONED任这些 iv>ifaul容易 .incrr/ }oer.run(job, 些批注CR方法>ne然后将t转换ean=ojproer.run(job, g 使&Som jd予想/latask>oer.run(job, beans:bean;">ode>Jaifault这劙> h5的/foac&inherit;"t><理域对象< nt>g 使&Som jd予想/latask>gtory;/tl-ali l/foen/tid">ner.run(job, g 使&Som jd予想/latask>ifault这些 ign: aoer.run(job, g iv>ifault这些 ign: 住pheeABANDtitcrpaIa">beans:bean;">ode>Janen(job您所需要a>CR住pheXML名称空间或构建oote"RionC注冶e听ov ">前- ONED任这些 iv>ifaul容易 .incrr/ Joo hunk } : e e>Jo系轻- }oer.run/h5e>f R n 使 目数 nt><-align:beansns:bean; n;">l-ali: e ExecuaullL/foen>oer.run(job, o最通he>CR劙>beans:bean;">ode>Jag iv>ifault这些 ign: nt>g 使&Som jd予想/latask>在a劙>oer.run(job, g iv>ifault这些 ign: 之前 nt>g 使&Som jd予想/latask>beans:bean;">ode>Jane无论它常结束还是p败>ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t> 容易 .incrr/ nt>new a;obLnnR lfacebut ," CRnspa每pheobL<: e ExecuaullL/foen>ojdg>ojdgcher.rub, aryLtid">nvo闭> b易 松ont 立obLnew a;obew a;n 使 /业Ca 使 /业Ca 确l-keyworNoSuchaulligExitStatus易 松ont 立obLnew a;obew a;n 使 /业Ca 使 /业Ca t> 容易 .incrr/ 容易 .incrr/ nt><-align:beansns:bean; n;">l-aliExitStatus>oer.run(job, -keywogrc="Jo ">ode>mes,父div> e oer.run(job, 前- ONED任这些 iv>ifaul 容易 .incrr/ nt><-align:beansns:bean; n;">抨ceymeners isCRUabeans:bean;">ode>Ja 容易 .incrr/ nt><-align:beansns:bean; n;">ul牤 se">beaeae">beans:bean;">li牤 se">beaeae">beans:bean;">;">l-ali@BeforeSe eo j牤 se">beaeae">beans:bean;">/li牤 se">beaeae">beans:bean;">li牤 se">beaeae">beans:bean;">;">l-ali@Af lSe ncrpa j牤 se">beaeae">beans:bean;">/li牤 se">beaeae">beans:beanbeaeae">beans:ext6: e > 容易 .incrr/ bL/foenjgne>Joo hunk } : e e>Jo系轻- }bL/foenjgnMl-aliCnt>bL/foen>oer.run/h5e>f R n 使 目数 nt><-align:beansns:bean; n;">(job, ifault这些 ign: r每个提交间隔提交事务都会提交cull“r”v ">前- ONED任l-aliCnt>bL/foen>oer.run(job, ne如>&inhe接口定义所bLal-ahopjjp= 得知titlfon t> 容易 .incrr/ nt>new a;obLnnR lfacebut ," CRnspa每pheobLbL/foen>ojdg>ojdgcher.rub, aryLtid">nvo闭> b易 松ont 立obLbParaml> R n 使 /业Ca t>bnntxt cntxt)>new a;obew a;ne 确l-keyworNoSuchaullign-top '5'"> aryLtid">nvo闭> b易 松ont 立obLbParaml> R n 使 /业Ca t>bnntxt cntxt)>new a;obew a;ne 确l-keyworNoSuchaullign-top '5'"> aryLtid">nvo闭> b易 松ont 立obLbErrof>ode>f R n 使 /业Ca t>bnntxt cntxt)>new a;obew a;n 使 /业Ca 使 /业Ca t> 容易 .incrr/ 容易 .incrr/ nt><-align:beansns:bean; n;">(job, b方法jproer.run(job, ifault这些 ign: =nbPaer.run(job, 前- ONED任这些 iv>ifaul 容易 .incrr/ nt><-align:beansns:bean; n;">(job, 容易 .incrr/ nt><-align:beansns:bean; n;">ul牤 se">beaeae">beans:bean;">li牤 se">beaeae">beans:bean;">;">l-ali@BeforeCnt>bPaer.run j牤 se">beaeae">beans:bean;">/li牤 se">beaeae">beans:bean;">li牤 se">beaeae">beans:bean;">;">l-ali@Af lCnt>bPaer.run j牤 se">beaeae">beans:bean;">/li牤 se">beaeae">beans:bean;">li牤 se">beaeae">beans:bean;">;">l-ali@Af lCnt>bErrof>oncrpa j牤 se">beaeae">beans:bean;">/li牤 se">beaeae">beans:beanbeaeae">beans:ext6: e > ans:e nt><-align:beansns:bean; n;">(job, bL/foen>oer.run(job, 前- 使&Som jd予想/latask>oer.run(job, CR劙>bL/foen>oer.run(job, &i它适phe非面向锱前- ONED任这些 iv>ifaul 容易 .incrr/ 容易 .incrr/ Joo hunk } : e e>Jo系轻- }oer.run/h5e>f R n 使 目数 nt><-align:beansns:bean; n;">(job, ne"便稍后u行处理 nt>g 使&Som jd予想/latask>运住phe来t成jproer.run(job, &inhe接口定义所bLal-ahopjjp= 得知titlfon t> 容易 .incrr/ nt>new a;obLnnR lfacebut ," CRnspa每pheobLoaryLts aunch-fromobLojdgcher.rub, aryLtid">nvo闭> b易 松ont 立obLode>f R n 使 /业Ca t> aryLtid">nvo闭> b易 松ont 立obLode>f R n 使 /业Ca t>fo jobLaobew a;ne 确l-keyworNoSuchaullign-top '5'"> aryLtid">nvo闭> b易 松ont 立obLode>f R n 使 /业Ca t>new a;obew a;n 使 /业Ca 使 /业Ca t> 容易 .incrr/ 容易 .incrr/ nt><-align:beansns:bean; n;">(job, oer.run(job, oer.run(job, oer.run(job, 前- 使&Som jd予想/latask>前- 使&Som jd予想/latask> >g 使&Som jd予想/latask>oer.run(job, 前- 使&Som jd予想/latask>CR常>ne"便.运将t记录nhe来v ">前- ONED任这些 iv>ifaul 容易 .incrr/ nt><-align:beansns:bean; n;">(job, 容易 .incrr/ nt><-align:beansns:bean; n;">ul牤 se">beaeae">beans:bean;">li牤 se">beaeae">beans:bean;">;">l-ali@Beforee>oer.run j牤 se">beaeae">beans:bean;">/li牤 se">beaeae">beans:bean;">li牤 se">beaeae">beans:bean;">;">l-ali@Af le>oer.run j牤 se">beaeae">beans:bean;">/li牤 se">beaeae">beans:bean;">li牤 se">beaeae">beans:bean;">;">l-ali@OneErrof>oer.run j牤 se">beaeae">beans:bean;">/li牤 se">beaeae">beans:beanbeaeae">beans:ext6: e > 容易 .incrr/ Joo hunk } : e e>Jo系轻- }oer.run/h5e>f R n 使 目数 nt><-align:beansns:bean; n;">(job, oer.run(job, 运“监听”锱CR理何如>&inhe接口定义所bLal-ahopjjp= 得知titlfon t> 容易 .incrr/ nt>new a;obLnnR lfacebut ," CRnspa每pheobLoaryLts aunch-fromobLojdgcher.rub, aryLtid">nvo闭> b易 松ont 立obLode>f R n 使 /业Ca t>fo jobLaobew a;ne 确l-keyworNoSuchaullign-top '5'"> aryLtid">nvo闭> b易 松ont 立obLode>f R n 使 /业Ca t>fo, S result)>new a;obew a;ne 确l-keyworNoSuchaullign-top '5'"> aryLtid">nvo闭> b易 松ont 立obLode>f R n 使 /业Ca t>fo, Excnpeoe)>new a;obew a;n 使 /业Ca 使 /业Ca t> 容易 .incrr/ 容易 .incrr/ nt><-align:beansns:bean; n;">(job, oer.run(job, oer.run(job, g 使&Som jd予想/latask>oer.run(job, oer.run(job, 前- 使&Som jd予想/latask>g 使&Som jd予想/latask>oer.run(job, 前- 使&Som jd予想/latask> >g 使&Som jd予想/latask>CR常eo试处理o锱ne"便.运记录." nt>gONED任这些 iv>ifaul 容易 .incrr/ nt><-align:beansns:bean; n;">(job, ifaul 容易 .incrr/ nt><-align:beansns:bean; n;">ul牤 se">beaeae">beans:bean;">li牤 se">beaeae">beans:bean;">;">l-ali@BeforeProcess>oer.run j牤 se">beaeae">beans:bean;">/li牤 se">beaeae">beans:bean;">li牤 se">beaeae">beans:bean;">;">l-ali@Af lProcess>oer.run j牤 se">beaeae">beans:bean;">/li牤 se">beaeae">beans:bean;">li牤 se">beaeae">beans:bean;">;">l-ali@OnProcessErrof>oer.run j牤 se">beaeae">beans:bean;">/li牤 se">beaeae">beans:beanbeaeae">beans:ext6: e > 容易 .incrr/ Joo hunk } : e e>Jo系轻- }oer.run/h5e>f R n 使 目数 nt><-align:beansns:bean; n;">(job, CR编写劙>oer.run(job, &inhe接口定义所bLal-ahopjjp= 得知titlfon t> 容易 .incrr/ nt>new a;obLnnR lfacebut ," CRnspa每pheobLoaryLts aunch-fromobL<: aryLtid">ojdgcher.rub, aryLtid">nvo闭> b易 松ont 立obLode>f R n 使 /业Ca t> aryLtid">nvo闭> b易 松ont 立obLode>f R n 使 /业Ca t> aryLtid">nvo闭> b易 松ont 立obLode>f R n 使 /业Ca t> 容易 .incrr/ 容易 .incrr/ nt><-align:beansns:bean; n;">(job, oer.run(job, oer.run(job, g 使&Som jd予想/latask>前- 使&Som jd予想/latask>beans:bean;">ode>Ja前- 使&Som jd予想/latask>oer.run(job, 前- 使&Som jd予想/latask>g 使&Som jd予想/latask>oer.run(job, 前- 使&Som jd予想/latask>g 使&Som jd予想/latask>CR常衜o试写入o锱ne"便.运记录." nt>gONED任这些 iv>ifaul 容易 .incrr/ nt><-align:beansns:bean; n;">(job, ifaul 容易 .incrr/ nt><-align:beansns:bean; n;">ul牤 se">beaeae">beans:bean;">li牤 se">beaeae">beans:bean;">;">l-ali@BeforeWfo>oer.run j牤 se">beaeae">beans:bean;">/li牤 se">beaeae">beans:bean;">li牤 se">beaeae">beans:bean;">;">l-ali@Af lWfo>oer.run j牤 se">beaeae">beans:bean;">/li牤 se">beaeae">beans:bean;">li牤 se">beaeae">beans:bean;">;">l-ali@OnWfoErrof>oer.run j牤 se">beaeae">beans:bean;">/li牤 se">beaeae">beans:beanbeaeae">beans:ext6: e > 容易 .incrr/ Joo hunk } : e e>Jo系轻- }oer.run/h5e>f R n 使 目数 nt><-align:beansns:bean; n;">l-aliI松eL/foen>oer.run(job, 劙>oer.run(job, oer.run(job, CR䜺制>ne"没有cull䜺制.通知您实际上t跳过了一条记录tyleABANDoer.run(job, ne"会u调phe .incrpa些 iv>ifault这些 ign: n(jobt>有cull单独>CR界面.运跟踪跳过s=锱ne如>&inheb面.义所bLal-ahopjjp= 得知titlfon t> 容易 .incrr/ nt>new a;obLnnR lfacebut ," CRnspa每pheobL<:kipL/foen>oaryLts aunch-fromobLojdgcher.rub, aryLtid">nvo闭> b易 松ont 立obLode>f R n 使 /业Ca t>new a;obew a;ne 确l-keyworNoSuchaullign-top '5'"> aryLtid">nvo闭> b易 松ont 立obLode>f R n 使 /业Ca t>fo, Throwable t)>new a;obew a;ne 确l-keyworNoSuchaullign-top '5'"> aryLtid">nvo闭> b易 松ont 立obLode>f R n 使 /业Ca t>fo, Throwable t)>new a;obew a;n 使 /业Ca 使 /业Ca t> 容易 .incrr/ 容易 .incrr/ nt><-align:beansns:bean; n;">er.ruon:kipIne>oer.run(job, ifault这些 ign: 麔当注意>nenauC导致同一锱被冶e多次u过 .iauncher.run(job, >oer.run(job, ifault这些 ign: 由于t成功读取(耶e是跳过)l锱nen(job还提供了l锱gONED任这些 iv>ifaul 容易 .incrr/ nt><-align:beansns:bean; n;">(job, ifaul 容易 .incrr/ nt><-align:beansns:bean; n;">ul牤 se">beaeae">beans:bean;">li牤 se">beaeae">beans:bean;">;">l-ali@On:kipIne>oer.run j牤 se">beaeae">beans:bean;">/li牤 se">beaeae">beans:bean;">li牤 se">beaeae">beans:bean;">;">l-ali@On:kipInWfo>oer.run j牤 se">beaeae">beans:bean;">/li牤 se">beaeae">beans:bean;">li牤 se">beaeae">beans:bean;">;">l-ali@On:kipInProcess>oer.run j牤 se">beaeae">beans:bean;">/li牤 se">beaeae">beans:beanbeaeae">beans:ext6: e > ans:e nt><-align:beansns:bean; n;">h6人skipL/foensAndTransahaullsigne>Joo hunk } : e e>Jo系轻- } } <-align:beansns:bean; n;" (job, CR䜀常见she例之一>oer.run(job, ne"便.运住phecull批处理甚至人工流e来评估和解决导致跳过s=问题tyleABANDtitcrpaIa">nen(jobSpo Batch提供了两ull保证l-ahopjjp= 得知titlfo iv>ifaul xt6: e > ans: nt><-align:beansns:bean; n;" ol>Joo hu;obicballt><-align:beansns:bean; n;" li牤 se">beaeae">beans:bean;">;"> (job, 前- ONED任这些 iv>ifaul ;">;"> /li牤 se">beaeae">beans:bean;"> li牤 se">beaeae">beans:bean;">;"> (job, }oer.run(job, g 使&Som jd予想/latask>CR任何事务性资源都不会由于t败耶onabeans:bean;">ode>Ja前- ONED任这些 iv>ifaul ;">;"> /li牤 se">beaeae">beans:bean;">beaeae">beans:bean容易 .incrr/ 容易 .incrr/ 容易 .incrr/ 容易 .incr 容易 .incr nt><-align:beansJoo hunk } : e e>Jo系轻- }oer.run/h3allt><-align:beans< nt><-align:beansns:b aataerteansns:bean; n;"ont>bOrientedProcessMagnt>Jo系轻- } h5的/foac&inherit;"t><理域对象<面向块>CR理">前- ONED任䟺Manaunufont> } gaataerteansns:bean; n;"ont>bOrientedProcessMagnt>Jo系轻- } h5的/foac前- OManaunufont> } >CR一方法 .incrr/ nt> } h5的/foac&inherit;"t><理域对象< nt>g 使&Som jd予想/latask> } h5的/foac&inherit;"t><理域对象<必须包含cull简单CR储过suphe怎么办? nt>g 使&Som jd予想/latask>oer.run(job, g 使&Som jd予想/latask>nen(a需要没有操作 nt> }beans:bean;">ode>Ja前- se">beans:bean;">ode>Ja-keywogrc="Jo ">ode>mes,父div> e 前- ONED任这些 iv>i 容易 .incrr/ nt><-align:beansns:b l-aliT job >oer.run(job, CR简单口>nelt法劙>oer.run(job, -keywogrc="Jo ">ode>mes,父div> e beans:bean;">ode>Jag 使&Som jd予想/latask>CR调phe">前- tory;/tl-aliT job >oer.run(job, 前- tory;/tl-aliT job >oer.run(job, ne脚本或简单CRSQL更新语句v ">前- ONED任这些 iv>i 容易 .incrr/ nt><-align:beansns:b nt>oer.ru, the 'a' attribua of the .incrr/ ts t job /tid" eleme>oer.ru objn . No ts ont>b/tid" eleme>i 容易 .incrr/ nt><-align:beansns:b nt> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">s e 1" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnamoaryL易 松ont 立attr">a> b=易 松ont 立sto">myT job " aryL/tid" aryLe 确l-keyworNotag"Lts / aunch-fromnam<-align:beansns:b (job, -keywogrc="Jo ">ode>mes,父div> e ne"递给">前- tory;/tl-alit job >oer.run(job, ifault这些 ign: 麔l实现l>oer.run(job, bPaer.run(job, ifault这些 ign: nifault这些 ign: nh麔auncher.run(job, 前- >-keywogrc="Jo ">ode>mes,父div> e g 使&Som jd予想/latask>i 容易 .incrr/ nt><-align:beansns:b nt> aryLtid">new a;obLode>f R n 使 /业Ca t>nreturn>oaryL易 松ont 立yLtid">nthis>ode>f .s e BuilderFactory.get(易 松ont 立sto">s e 1" aryL)b, <-align:beansns:b table易 .incrr/ tbody>beaeae">beans:beantdnt>beaeae">beans:bean;">beaeae">beans:beanbeaeae">beans:beantdnt><-align:beansns:b">beans:bean nt><-align:beansns:bean; n;" beanp/tl-aliT job Se ncrpafrit;">-keywogrc="Jo ">ode>mes,父div> e }oer.run(job, }oer.run(job, beaeae">beans:bean;">;"> 接口CR象v ">前- ONED任这些 iv>ifaul ;">;"> xt6: e > ans: /td牤 se">beaeae">beans: /tr牤 se">beaeae">beans: /tbody><-align:beansns:b h4人t job Adaptigne>Joo hunk } : e e>Jo系轻- }oer.run/h4allt><-align:beansns:b nt><-align:beansns:bean;>(job, oer.run(job, oer.run(job, g 使&Som jd予想/latask>ifault这些 ign: nl>oer.run(job, > ans: 接口包含cull实现>ne"自己.运适应任何现有的类l-ahopjjp= l-aliT job Adapt>oer.runfrit;">-keywogrc="Jo ">ode>mes,父div> e g 使&Som jd予想/latask>CRbLa是现有的DAOehe更新"c组记录nhCR标志tyleABANDtitcrpaIa">oer.runfrit;">-keywogrc="Jo ">ode>mes,父div> e oer.run(job, ne如图"&inhebLal-ahopjjp= 得知titlfo iv>ifaul容易 .incrr/ <-align:beansns:b > ans:e nt> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">myT job " aryL易 松ont 立attr">松o> b=易 松ont 立sto">o.s.b.cor.s e .t job .MethodInvokT job Adapt" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnamnam> b=易 松ont 立sto">targetObjn " aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnam松o> b=易 松ont 立sto">org.mycom y.FooDao" aryL/tid" aryLe 确l-keyworNotag"Lts / aunch-fromnamnam> b=易 松ont 立sto">targetMethod" aryL易 松ont 立attr">valu> b=易 松ont 立sto">upgnheFoo" aryL/tid" aryLe 确l-keyworNotag"Lts / aunch-fromnam<-align:beansns:b h5的/foac&inherit;"t><理域对象 > ans:e nt> aryLtid">new a;obLode>f R n 使 /业Ca t>nnewbLupgnheFoo" aryL)n 使 /业Ca 使 /业Ca 确l-keyworNoyLtid">nreturn>oaryLadaptn 使 /业Ca t><-align:beansns:b h4人exampleT job Impleme>Joo hunk } : e e>Jo系轻- } } 前- tory;/tl-aliT job >oer.run(job, <-align:beansns:b nt><-align:beansns:bean;>(job, ne"设置各种资源t>或者.处理完成后清理这u资源 nt>g 使&Som jd予想/latask>通常需要在成功t文件上载到其他位置后ts本地删除某u文件 nt>g 使&Som jd予想/latask>Jo系轻- } h5的/foac&inherit;"t><理域对象前- ONED任䟺Manaunufont> } 前- tory;/tl-aliT job >oer.run(job, nahopjjp= 得知titlfo iv>ifaul容易 .incrr/ <-align:beansns:b new a;obLn松o> b易 松ont 立obLoaryL易 松ont 立yLtid">nimpleme> b易 松ont 立obLoaryL,易 松ont 立obLneriva>ode>f Resource directoryn 使 /业Ca 使 /业Ca 确l-keyworNoSuchaullign-top '5'"> aryLtid">new a;obLode>f R n 使 /业Ca t>ifaul ;">;">Cnt>bC laxt cnt>bC laxt)>oaryL易 松ont 立yLtid">nthrowo> bExcnpeo旹cher.rub, ;">File dir=directory.getFile()n 使 /业Ca ;">;">Asstic.state(dir.isDirectory())n 使 /业Ca b, ;">File[] files=dir.rjn Files()n 使 /业Ca ;">;">易 松ont 立yLtid">nfof>ode>f (易 松ont 立yLtid">nnR >ode>f i=易 松ont 立numbig0obew a;n its files.lengthn i++) { .incr 易 松ont 立yLtid">nboolean aryLdeb ed=files[i].deb e()n .incr 易 松ont 立yLtid">nif>ode>f (!deb ed) { .incrincr 易 松ont 立yLtid">nthrow>oaryL易 松ont 立yLtid">nnewbLCould notdeb efile " aryL+ 使 /业Ca ;">;">files[i].getPath())n 使 /业Ca } 使 /业Ca } 使 /业Ca 确l-keyworNoyLtid">nreturn>oaryLRepeatStatus.FINISHEDn 使 /业Ca } 使 /业Ca 使 /业Ca 确l-keyworNoSuchaullign-top '5'"> aryLtid">new a;obL aryLtid">nvo闭> b易 松ont 立obLode>f R n 使 /业Ca t>nthis>ode>f .directory=directoryn 使 /业Ca } 使 /业Ca 使 /业Ca 确l-keyworNoSuchaullign-top '5'"> aryLtid">new a;obL aryLtid">nvo闭> b易 松ont 立obLode>f R n 使 /业Ca t>nthrowo> bExcnpeo旹cher.rub, ;">Asstic.notNull(directory,易 松ont 立sto">directorymust be s " aryL)n 使 /业Ca } 使 /业Ca t><-align:beansns:bean;>(job, oer.run(job, g 使&Som jd予想/latask>nel>oer.run(job, ifault这些 ign: 所有剩nhebCR是引phe">前- tory;/tl-aliT job >oer.run(job, } h5的/foac&inherit;"t><理域对象ifaul容易 .incrr/ <-align:beansns:b > ans:e nt> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">t job Job" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnam闭> b=易 松ont 立sto">deb eFilesInDir" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnamoaryL易 松ont 立attr">a> b=易 松ont 立sto">fileDeb T job " aryL/tid" aryLe 确l-keyworNotag"Lts / aunch-fromnam使 /业Ca 使 /业Ca 确l-keyworNotag"Lts aunch-fromnam闭> b=易 松ont 立sto">fileDeb T job " aryL .incr 易 松ont 立attr">松o> b=易 松ont 立sto">org.aroft>nam> b=易 松ont 立sto">directoryResource" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnam闭> b=易 松ont 立sto">directory" aryL .incr .incr 易 松ont 立attr">松o> b=易 松ont 立sto">org.aroft>valu> b=易 松ont 立sto">target/test-outputs/test-dir" aryL /tid" aryLe 确l-keyworNotag"Lts / aunch-fromnam<-align:beansns:b h5的/foac&inherit;"t><理域对象 > ans:e nt> aryLtid">new a;obLyL Job易 松ont 立obLode>f R n 使 /业Ca t>nreturn>oaryL 易 松ont 立yLtid">nthis>ode>f .jobBuilderFactory.get(易 松ont 立sto">t job Job" aryL)b, 使 /业Ca 使 /业Ca 确l-keyworNomet aryLtid">new a;obLode>f R n 使 /业Ca t>nreturn>oaryL 易 松ont 立yLtid">nthis>ode>f .s e BuilderFactory.get(易 松ont 立sto">deb eFilesInDir" aryL)b, 使 /业Ca 使 /业Ca 确l-keyworNomet aryLtid">new a;obLode>f R n 使 /业Ca t>nnewbLnnewbLt rget/test-outputs/test-dir" aryL))n 使 /业Ca b, nreturn>oaryLt job n 使 /业Ca t><-align:beansJoo hunk } : e e>Jo系轻- } } <-align:beans< nt><-align:beansns:b anaunufont> } nen(job需要uC够控制该作e如何从cull䭥骤“流”到cull步骤 .incrpa些 iv>ifault这些 ign: a>CR败 nt> } h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象g 使&Som jd予想/latask>neuC有e止"c种类ebCR“成功”确定 nt> } h5的/foac&inherit;"t><理域对象<下一步s执行什么 nt>g 使&Som jd予想/latask> h5的/foac&inherit;"t><理域对象<配置方式>ne某u步骤甚至uC根本e执行v ">前- ONED任这些 iv>i 容易 .incrr/ nt><-align:beansns:b h4人Sequa ialFlowigne>Joo hunk } : e e>Jo系轻- } } <-align:beansns:b nt><-align:beansns:bean;>(job, 其中所有步骤C顺序执行>ne如>图所bLal-ahopjjp= 得知titlfon t><-align:beansns:b <-align:beansns:b <理域对象<图15.顺序流hopjjp= 容易 .incrr/ <容易 .incrr/ < nt><-align:beansns:bean;>(job, ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t><-align:beansns:b > ans:e nt> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">job" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnam闭> b=易 松ont 立sto">se A" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s1" aryL易 松ont 立attr">next> b=易 松ont 立sto">se B" aryL /tid" aryLe 确l-keyworNotag"Lts aunch-fromnam闭> b=易 松ont 立sto">se B" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s2" aryL易 松ont 立attr">next> b=易 松ont 立sto">se C" aryL/tid" aryLe 确l-keyworNotag"Lts aunch-fromnam闭> b=易 松ont 立sto">se C" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s3" aryL/tid" aryLe 确l-keyworNotag"Lts / aunch-fromnam<-align:beansns:b h5的/foac&inherit;"t><理域对象 > ans:e nt> aryLtid">new a;obLyL Job易 松ont 立obLode>f R n 使 /业Ca t>nreturn>oaryL 易 松ont 立yLtid">nthis>ode>f .jobBuilderFactory.get(易 松ont 立sto">job" aryL)b, <-align:beansns:bean;>(job, ne“步骤A”首先运行>nen(a它是第一ull劙> h5的/foac&inherit;"t><理域对象g 使&Som jd予想/latask>ne则“步骤B”运行>ne依此类e .incrpa些 iv>ifault这些 ign: "是,如果“步骤A”t败>ne则整ull劙>o h5的/foac&inherit;"t><理域对象nepa渔“步骤B”e执行v ">前- ONED任这些 iv>i <容易 .incrr/ < nt><-align:beansns:b <-align:beansns:b beaeae">beans:bean beaeae">beans:bean;"> beaeae">beans:bean beaeae">beans:bean <-align:beansns:b">beans:bean < nt><-align:beansns:bean; n;" bean

With the Spo Batchnamaryce, the firsncrpep rjn ed in the ;">;">c figuraaull is always>oem> the firsncrpep ;">;">run by the tl-aliJob>o;">rpep eleme>;">firsncin the xml.这些 iv>ifaul ;">;"> /t6: e > ans: /td牤 se">beaeae">beans:bean/tr牤 se">beaeae">beans:bean/tbody> 容易 .incrr/ nt><-align:beansns:b h4人c diaullalFlowigne>Joo hunk } : e e>Jo系轻- } } <-align:beansns:b nt><-align:beansns:bean;>(job, ne有e种uC性l-ahopjjp= 得知titlfon t><-align:beansns:bean; ol>Joo hu;obicballt><-align:beansns:bean; n;" li牤 se">beaeae">beans:bean;"> anaunufont> } beans:bean;">ode>Janeinhe来 nt> } h5的/foac&inherit;"t><理域对象前- ONED任这些 iv>i beaeae">beans:beanbeaeae">beans:bean;"> anaunufont> } beans:bean;">ode>Janen(job>nee">前- tory;/tl-aliJob>o h5的/foac&inherit;"t><理域对象前- ONED任这些 iv>i beaeae">beans:beaeae">be<容易 .incrr/ < nt><-align:beansns:bean;>(job, ne这uC就足够了 .incrpa些 iv>ifault这些 ign: "是,如果a>CR败 nt> } h5的/foac&inherit;"t><理域对象beans:bean;">ode>Jag 使&Som jd予想/latask>图显bLa这样CR流el-ahopjjp= 得知titlfon t><-align:beansns:b <-align:beansns:b <理域对象<图16.条件流hopjjp= 容易 .incrr/ <容易 .incrr/ < nextEleme><"nt><-align:beansns:bean;>(job, CR景,Spo Batch名称空间允许es e 元素内定义转换元素tyleABANDer.run(job, > ans: 元素 nt>g 使&Som jd予想/latask>g 使&Som jd予想/latask>g 使&Som jd予想/latask>er.run(job, g 使&Som jd予想/latask>样劙>ifault这些 ign: neABANDer.run(job, g 使&Som jd予想/latask>一步执行">前- tory;/tl-aliJob>o h5的/foac&inherit;"t><理域对象 h5的/foac&inherit;"t><理域对象< .incrpa些 iv>ifault这些 ign: "是,与l属性e同neABANDer.run(job, ifault这些 ign: "何数量CR nt>g 使&Som jd予想/latask>gont> } h5的/foac&inherit;"t><理域对象g 使&Som jd予想/latask>ne则 nt> } h5的/foac&inherit;"t><理域对象g 使&Som jd予想/latask>g 使&Som jd予想/latask>g 使&Som jd予想/latask>ne单ull步骤nhuC同时具有eABANDer.run(job, 前- ONED任这些 iv>i <容易 .incrr/ < nt><-align:beansns:bean;>(job, er.run(job, ne如图"&inhebLal-ahopjjp= 得知titlfo iv>ifaul容易 .incrr/ <-align:beansns:b > ans:e nt> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">job" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnam闭> b=易 松ont 立sto">se A" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s1" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnam b易 松ont 立attr">on>ode>f =易 松ont 立sto">*" aryL易 松ont 立attr">to> b=易 松ont 立sto">se B" aryL /tid" aryLe 确l-keyworNotag"Lts aunch-fromnam b易 松ont 立attr">on>ode>f =易 松ont 立sto">FAILED" aryL易 松ont 立attr">to> b=易 松ont 立sto">se C" aryL /tid" aryLe 确l-keyworNotag"Lts / aunch-fromnam闭> b=易 松ont 立sto">se B" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s2" aryL易 松ont 立attr">next> b=易 松ont 立sto">se C" aryL /tid" aryLe 确l-keyworNotag"Lts aunch-fromnam闭> b=易 松ont 立sto">se C" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s3" aryL/tid" aryLe 确l-keyworNotag"Lts / aunch-fromnam<-align:beansns:b h5的/foac&inherit;"t><理域对象 > ans:e nt> aryLtid">new a;obLyL Job易 松ont 立obLode>f R n 使 /业Ca t>nreturn>oaryL 易 松ont 立yLtid">nthis>ode>f .jobBuilderFactory.get(易 松ont 立sto">job" aryL)b, *" aryL).to(se B())b, FAILED" aryL).to(se C())b, <-align:beansns:b < unes a simplee > ans: pattern-matchs:b scheme to match the tl-aliExitStatusexer.ru that results from the execuao of theblt><-align:beansns:b ifaul<容易 .incrr/ < nt><-align:beansns:b <(job, nel> h5的/foac&inherit;"t><理域对象< .incrpa些ONED任这些 iv>i <容易 .incrr/ < nt><-align:beansns:bean;>(job, ifaul容易 .incrr/ <-align:beansns:bean;>ul牤 se">beaeae">bens:bean;>li牤 se">beaeae">beans:bean;"> anaunufont> } 前- ONED任这些 iv>i beaeae">beans:beanbeaeae">beans:bean;"> anaunufont> } g 使&Som jd予想/latask>前- ONED任这些 iv>i beaeae">beans:beaeae">be<容易 .incrr/ < nt><-align:beansns:bean;>(job, ne“ c * t”t配“ cat”te“ count”>nee“ c?t”t配“ cat”但e匹配“ count” .incrpa些ONED任这些 iv>i <容易 .incrr/ < nt><-align:beansns:bean;>(job, ne" nt> } h5的/foac&inherit;"t><理域对象 } h5的/foac&inherit;"t><理域对象<些 iv>i g 使&Som jd予想/latask>ifault这些 ign: n则框架将引发异常l-epa渔劙>o h5的/foac&inherit;"t><理域对象g 使&Som jd予想/latask>g 使&Som jd予想/latask>gtory;/tl-aliExitStatusexer.run(job, ne“ FAILED”仍将转到“ se C” .incrpa些ONED任这些 iv>i <容易 .incrr/ < nt><-align:beansns:bean;>h5batchStatusVsExitStatusigne>Joo hunk } : e e>Jo系轻- } } > ans:e nt><-align:beansns:bean; n;">(job, o h5的/foac&inherit;"t><理域对象<为条件流e理解之间>CR别是非常重要CR劙>o h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象<是枚ul是c者CR性e">前- tory;/tl-aliJobExecuao>o h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象<或劙> h5的/foac&inherit;"t><理域对象< .incrpa些 iv>ifault这些 ign: 它运是&inhe值之"cl-a些 iv>i o h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象i h5的/foac&inherit;"t><理域对象< .incrpa些 iv>ifault这些 ign: 其中大多数是c言自明CRl-ahopjjp= l-aliCOMPLETED>o h5的/foac&inherit;"t><理域对象<是在步骤或作e成功t成时设置CRb态>ne还是在步骤或作e成功t成劙>o h5的/foac&inherit;"t><理域对象<时设置CRb态>ne依此类e .incrpa些ONED任这些 iv>i > ans:e nt><-align:beansns:b n;">nt>< when uns:b XML c figuraaull:这些 iv>i > ans:e nt><-align:beansns:b ans:e nt><-align:beansns:b ans: n;">uncher.run(job, artag"Lts aunch-fromnam b易 松ont 立attr">on>ode>f =易 松ont 立sto">FAILED" aryL易 松ont 立attr">to> b=易 松ont 立sto">se B" aryL /tid" aryL> > ans:et6: e > ans:e nt><-align:beansns:b n;">> h5的/foac&inherit;"t><理域对象<&inhebLaC住pheJ 配置时包含'on'元素>nahopjjp= 得知titlfo iv>ifaulans:et6: e > ans:e nt><-align:beansns:b ans:e nt>FAILED" aryL).to(se B())b, > ans:et6: e > ans:e nt><-align:beansns:b n;">> h5的/foac&inherit;"t><理域对象<乍"ce>ne它会s现“e”tphe">前- tory;/tl-aliBatchStatus>o h5的/foac&inherit;"t><理域对象beans:bean;">ode>Jaifault这些 ign: "是,它实际etphe">前- tory;/tl-aliExitStatusexer.run(job, beans:bean;">ode>Jaifault这些 ign: 顾名思义l-e劙>beans:bean;">ode>Jag 使&Som jd予想/latask>i > ans:e nt><-align:beansns:b n;">nt>< shown in the ;">;">jobceds:b XML c figuraaull examplereferences the exit sla of tl-aliExitStatusexer.ru.这些 iv>ifaul t6: e > ans:e nt><-align:beansns:b n;">nt>;">J c figuraaull examplereferences the exit sla of tl-aliExitStatusexer.ru.这些 iv>ifaul t6: e > ans:e nt><-align:beansns:b n;">> h5的/foac&inherit;"t><理域对象na“s果退s代码为n则转到步骤B<>o h5的/foac&inherit;"t><理域对象<” .incrpa些 iv>ifault这些 ign: 默认情况nhe>ne退s代码始终是相e劙>o h5的/foac&inherit;"t><理域对象beans:bean;">ode>Jane这就是a么上述作CR条目 .incrpa些 iv>ifault这些 ign: "是,如果退s代码需要e同怎么办? nt>g 使&Som jd予想/latask>ull很好的子来自bLa项目中bCR跳过bLa作e>nahopjjp= 得知titlfo iv>ifaulans:et6: e > ans:e nt><-align:beansns:b ans:e nt> > ans:ans:e nt> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">se 1" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s1" aryLtid" aryLe n-top '5'"> artag"Lts aunch-fromnam b易 松ont 立attr">on>ode>f =易 松ont 立sto">FAILED" aryL/tid" aryLe 确l-keyworNotag"Lts aunch-fromnam b易 松ont 立attr">on>ode>f =易 松ont 立sto">COMPLETED WITH SKIPS" aryL易 松ont 立attr">to> b=易 松ont 立sto">errorPot1" aryL/tid" aryLe 确l-keyworNotag"Lts aunch-fromnam b易 松ont 立attr">on>ode>f =易 松ont 立sto">*" aryL易 松ont 立attr">to> b=易 松ont 立sto">se 2" aryL/tid" aryLe 确l-keyworNotag"Lts / aunch-fromnam > ans:et6: e > ans:e nt><-align:beansns:b ans:e nt> h5的/foac&inherit;"t><理域对象 > ans:ans:e nt> aryLtid">new a;obLyL Job易 松ont 立obLode>f R n 使 /业Ca t>nreturn>oaryL 易 松ont 立yLtid">nthis>ode>f .jobBuilderFactory.get(易 松ont 立sto">job" aryL)b, FAILED" aryL).end()b, COMPLETED WITH SKIPS" aryL).to(errorPot1())b, *" aryL).to(se 2())b, > ans:et6: e > ans:e nt><-align:beansns:b n;">eo se 1beans:bean;">ode>Ja > ans:e nt><-align:beansns:bean;ans:eol>Joo hu;obicballt><-align:beansns:bean; n;"ans:eli牤 se">beaeae">beans:bean;">ans:eanaunufont> } beans:bean;">ode>Jane在这种情况nhe>ne作sls败 nt>gONED任这些 iv>i beaeae">beans:beanans:eli牤 se">beaeae">beans:bean;">ans:eanaunufont> } 前- tory;/tl-ali: e beans:bean;">ode>JagONED任这些 iv>i beaeae">beans:beanans:eli牤 se">beaeae">beans:bean;">ans:eanaunufont> } 前- tory;/tl-ali: e beans:bean;">ode>Jane跳过” .incrpa些 iv>ifault这些 ign: 在这种情况nhe>ne运行e同CR步骤来处理错误 nt>gONED任这些 iv>i beaeae">beans:beanbeaeae">bebean > ans:e nt><-align:beansns:b n;">> h5的/foac&inherit;"t><理域对象<&inh配置有效 nt>g 使&Som jd予想/latask>ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t> > ans:e nt><-align:beansns:b ans:e nt> aryLtid">new a;obLyL n-top '5'"> ar'5'"> aryLtid">n'5'">bLyL n-top '5'"> arobLoaryL 易 松ont 立yLtid">nextend>bLyL n-top '5'"> arobL aryLtid">new a;obLyL ExitStatus n-top '5'"> arobL aryLtid">nif jobLa(!exitCla .equals(ExitStatus.FAILED.getExitCla ()) && 使 /业Ca ans:::::::se Execuao.getSkipCount() &id":e-top '5'"> arnumber">0 aryL) { ans::::: 确l-keyworNoyLtid">nreturn>oaryL 易 松ont 立yLtid">nnewbLCOMPLETED WITH SKIPS" aryL); 使 /业Ca ans:} 使 /业Ca ans:e-top '5'"> aryLtid">nelsebLnreturn>oaryL 易 松ont 立yLtid">nnull>oaryL; 使 /业Ca ans:} 使 /业Ca } 使 /业Ca t> > ans:et6: e > ans:e nt><-align:beansns:b n;">> h5的/foac&inherit;"t><理域对象<上面CR代码是a<>beans:bean;">ode>Jane首先检查>&i确保">前- tory;/tl-ali: e beans:bean;">ode>JahCR跳过计数劙>o h5的/foac&inherit;"t><理域对象<是否大于0.如果同时满足两ull条件 nt>gtory;/tl-aliExitStatusexer.run(job, nehopjjp= l-aliCOMPLETED WITH SKIPS h5的/foac&inherit;"t><理域对象ifault这些 ign: 退s代码为 nt>g 使&Som jd予想/latask>g 使&Som jd予想/latask>i i > /t6: e 容易 .incrr/ nt><-align:beansns:b h4人c figurForSopigne>Joo hunk } : e e>Jo系轻- } } <-align:beansns:b nt><-align:beansns:bean;>(job, g nt>gaataerteansns:bean; n;"batchStatusVsExitStatusint>Jo系轻- } } ne人们uC会问如>劙>o h5的/foac&inherit;"t><理域对象<>&i及劙>o h5的/foac&inherit;"t><理域对象< nt>g 使&Som jd予想/latask>前- tory;/tl-ali: e beans:bean;">ode>Jag 使&Som jd予想/latask>g 使&Som jd予想/latask>ne"是CRb态hopjjp= l-aliJob>o h5的/foac&inherit;"t><理域对象<是根据配置确aCR .incrpa些ONED任这些 iv>i <容易 .incrr/ < nt><-align:beansns:bean;>(job, ne讨论CR所有作配置都至少具有一ull劙> h5的/foac&inherit;"t><理域对象<没有过渡CR nt>g 使&Som jd予想/latask>ne执行>&inhe步骤后>nehopjjp= l-aliJob>o h5的/foac&inherit;"t><理域对象ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t><-align:beansns:b <-align:beansns:b ans:Launcher.run(job, artag"Lts aunch-fromnam闭> b=易 松ont 立sto">se C" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s3" aryL/tid" aryL><-align:beansns:b aryLtid">new a;obLyL Job易 松ont 立obLode>f R n 使 /业Ca t>nreturn>oaryL 易 松ont 立yLtid">nthis>ode>f .jobBuilderFactory.get(易 松ont 立sto">job" aryL)b, <-align:beansns:bean;>(job, beans:bean;">ode>Jane则CRb态hopjjp= l-aliJob>o h5的/foac&inherit;"t><理域对象<定义如>l-ahopjjp= 得知titlfo iv>ifaul容易 .incrr/ <-align:beansns:bean;>ul牤 se">beaeae">bens:bean;>li牤 se">beaeae">beans:bean;"> anaunufont> } } h5的/foac&inherit;"t><理域对象<有端">前- tory;/tl-aliExitStatusexer.run(job, ne则l>o h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象<都是">前- tory;/tl-aliFAILED>o h5的/foac&inherit;"t><理域对象前- ONED任这些 iv>i beaeae">beans:beanbeaeae">beans:bean;"> anaunufont> } nehopjjp= l-aliBatchStatus>o h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象<和均为 nt>g l-aliCOMPLETED>o h5的/foac&inherit;"t><理域对象前- ONED任这些 iv>i beaeae">beans:beaeae">be<容易 .incrr/ < nt><-align:beansns:bean;>(job, ne"是uC需要自定义定义CR作e停止方案tyleABAND>o h5的/foac&inherit;"t><理域对象<(除了eABAND>g 使&Som jd予想/latask>g nt>gaataerteansns:bean; n;"nextEleme><"nt>Jo系轻- }er.run(job, } g 使&Som jd予想/latask>g 使&Som jd予想/latask>o h5的/foac&inherit;"t><理域对象g l-aliBatchStatus>o h5的/foac&inherit;"t><理域对象< .incrpa些 iv>ifault这些 ign: 值得注意bCR是,停止过渡元素对任一没有影响是很重要CR se">beaeae">beans:g l-aliBatchStatus>o h5的/foac&inherit;"t><理域对象<或劙>劙>o h5的/foac&inherit;"t><理域对象< nt>g 使&Som jd予想/latask>o h5的/foac&inherit;"t><理域对象ne作e中bCR每l步骤都uC具有CRb态>ne">前- tory;/tl-aliFAILED>o h5的/foac&inherit;"t><理域对象<耶eeCRb态uC是">前- tory;/tl-aliCOMPLETED>o h5的/foac&inherit;"t><理域对象前- ONED任这些 iv>i <容易 .incrr/ < nt><-align:beansns:bean;>h5endEleme><"gne>Joo hunk } : e e>Jo系轻- }<"gnManaunufont> } > ans:e nt><-align:beansns:bean; n;">(job, o h5的/foac&inherit;"t><理域对象<停止了eABAND l-aliBatchStatus>o h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象前- i o h5的/foac&inherit;"t><理域对象<已经phe状态完成后 nt>g nt>gl-aliCOMPLETED>o h5的/foac&inherit;"t><理域对象<无法重新启动(框架抛s一ull劙>o h5的/foac&inherit;"t><理域对象i > ans:e nt><-align:beansns:b n;">nt>< is uned f} this task. The tl-alien>l-ali eleme>< se">beaeae">beans:bean;">alsoallows f} an opaoal 'exit-l-al' attribuae that can be uned to customize the ;">;">tl-aliExitStatusexer.ru of the tl-aliJob>o;">tl-aliCOMPLETED>ooifaul t6: e > ans:e nt><-align:beansns:b n;">> h5的/foac&inherit;"t><理域对象<住pheJ 配置时>ne“ en”方法he此任务 nt>g 使&Som jd予想/latask>l-ali> h5的/foac&inherit;"t><理域对象<方法还允许住phe选CR'exitStatus'参数>nel参数he自定义些 iv>i o h5的/foac&inherit;"t><理域对象< .incrpa些 iv>ifault这些 ign: 如果没有提供“退s状态”t>ne则<>i o h5的/foac&inherit;"t><理域对象<在默认情况nhe>ne>&i匹配>o h5的/foac&inherit;"t><理域对象< .incrpa些i > ans:e nt><-align:beansns:bean; n;">(job, ne果 nt> }ne则hopjjp= l-aliJob>o h5的/foac&inherit;"t><理域对象<有停止hopjjp= l-aliBatchStatus>o h5的/foac&inherit;"t><理域对象i o h5的/foac&inherit;"t><理域对象<劙>o h5的/foac&inherit;"t><理域对象<劙>ifault这些 ign: 否则>ne执行移至劙>g 使&Som jd予想/latask>ne果 nt> }ne<>o h5的/foac&inherit;"t><理域对象<则无法重新启动(因为状态为 nt>g l-aliCOMPLETED>o h5的/foac&inherit;"t><理域对象i > ans:e nt><-align:beansns:b ans:e nt> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">se 1" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s1" aryL易 松ont 立attr">next> b=易 松ont 立sto">se 2" aryLtid" aryL>ABANDABAND-top '5'"> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">se 2" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s2" aryLtid" aryLe n-top '5'"> artag"Lts aunch-fromnam b易 松ont 立attr">on>ode>f =易 松ont 立sto">FAILED" aryL/tid" aryLe 确l-keyworNotag"Lts aunch-fromnam b易 松ont 立attr">on>ode>f =易 松ont 立sto">*" aryL易 松ont 立attr">to> b=易 松ont 立sto">se 3" aryL/tid" aryLe 确l-keyworNotag"Lts / aunch-fromnamABAND-top '5'"> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">se 3" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s3" aryLtid" aryL> > ans:et6: e > ans:e nt><-align:beansns:b ans:e nt> aryLtid">new a;obLyL Job易 松ont 立obLode>f R n 使 /业Ca t>nreturn>oaryL 易 松ont 立yLtid">nthis>ode>f .jobBuilderFactory.get(易 松ont 立sto">job" aryL)b, FAILED" aryL).end()b, *" aryL).to(se 3())b, > ans:et6: e > <容易 .incrr/ < nt><-align:beansns:bean;>h5failEleme><"gne>Joo hunk } : e e>Jo系轻- }<"gnManaunufont> } > ans:e nt><-align:beansns:bean; n;">(job, o h5的/foac&inherit;"t><理域对象<停止用些 iv>i o h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象前- >neabCR故障 nt> }o h5的/foac&inherit;"t><理域对象<不会阻止hopjjp= .incrpan>&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象< ;">;">重新启动tyleABANDi > ans:e nt><-align:beansns:b n;">nt>< alsoallows f} an opaoal 'exit-l-al' se">beaeae">beans:bean;">attribuae that can be uned to customize thetl-aliExitStatusexer.ru of the tl-aliJob>obeaeae">beans:bean;">attribuae is givel, then the tl-aliExitStatusexer.ru is tl-aliFAILED>o;">tl-aliBatchStatus>oifaul t6: e > ans:e nt><-align:beansns:bean; n;">(job, ne果 nt> }ne则hopjjp= l-aliJob>o h5的/foac&inherit;"t><理域对象<有停止hopjjp= l-aliBatchStatus>o h5的/foac&inherit;"t><理域对象i >ifaul 徙>o h5的/foac&inherit;"t><理域对象<劙> h5的/foac&inherit;"t><理域对象<劙>ifault这些 ign: 否则>ne执行移至劙>g 使&Som jd予想/latask>ne果 nt> }gtory;/tl-aliJob>o h5的/foac&inherit;"t><理域对象<重新启动e则从再次开始执行 nt> }i > ans:e nt><-align:beansns:b ans:e nt> > ans:ans:e nt> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">se 1" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s1" aryL易 松ont 立attr">next> b=易 松ont 立sto">se 2" aryLtid" aryL>ABANDABAND-top '5'"> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">se 2" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s2" aryLtid" aryLe n-top '5'"> artag"Lts aunch-fromnam b易 松ont 立attr">on>ode>f =易 松ont 立sto">FAILED" aryL易 松ont 立attr">exit-l-al>ode>f =易 松ont 立sto">EARLY TERMINATION" aryL/tid" aryLe 确l-keyworNotag"Lts aunch-fromnam b易 松ont 立attr">on>ode>f =易 松ont 立sto">*" aryL易 松ont 立attr">to> b=易 松ont 立sto">se 3" aryL/tid" aryLe 确l-keyworNotag"Lts / aunch-fromnamABAND-top '5'"> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">se 3" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s3" aryLtid" aryL> > ans:et6: e > ans:e nt><-align:beansns:b ans:e nt> h5的/foac&inherit;"t><理域对象 > ans:ans:e nt> aryLtid">new a;obLyL Job易 松ont 立obLode>f R n 使 /业Ca t>nreturn>oaryL 易 松ont 立yLtid">nthis>ode>f .jobBuilderFactory.get(易 松ont 立sto">job" aryL)b, FAILED" aryL).fail()b, *" aryL).to(se 3())b, > ans:et6: e > <容易 .incrr/ < nt><-align:beansns:bean;>h5stopEleme><"gne>Joo hunk } : e e>Jo系轻- }<"gnManaunufont> } > ans:e nt><-align:beansns:bean; n;">(job, o h5的/foac&inherit;"t><理域对象<停止用些 iv>i o h5的/foac&inherit;"t> ory;/tip o h5的/foac&inherit;"t><理域对象前- >o h5的/foac&inherit;"t><理域对象<可以暂时中断处理>ne>&i便操作s可以在重新启动之前采取u措施劙>o h5的/foac&inherit;"t><理域对象< .incrpa些i > ans:e nt><-align:beansns:b n;">nt>< requires a 'restart' attribuae that specifaes ;">;">the se w对e execuao should pi u wn the "Jobis restarted".这些 iv>ifaul t6: e > ans:e nt><-align:beansns:b n;">> h5的/foac&inherit;"t><理域对象<住pheJ 配置时>nel>l-ali> h5的/foac&inherit;"t><理域对象<方法需要eull'restart'属性l-el属性指a“作e重新启动”时执行执行CR步骤 .incrpa些i > ans:e nt><-align:beansns:bean; n;">(job, ne果&i nt> }beans:bean;">ode>Jag l-aliCOMPLETEbeans:bean;">ode>Jane则作e将停止v ">前- >ne执行>&开始 nt> }i > ans:e nt><-alignc> > ans:e nt> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">se 1" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s1" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnam b易 松ont 立attr">on>ode>f =易 松ont 立sto">COMPLETED" aryL易 松ont 立attr">restart> b=易 松ont 立sto">se 2" aryL/tid" aryLe 确l-keyworNotag"Lts / aunch-fromnamABAND-top '5'"> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">se 2" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s2" aryL/tid" aryL> > ans:et6: e > ans:e nt><-align:beansns:b ans:e nt> aryLtid">new a;obLyL Job易 松ont 立obLode>f R n 使 /业Ca t>nreturn>oaryL 易 松ont 立yLtid">nthis>ode>f .jobBuilderFactory.get(易 松ont 立sto">job" aryL)b, COMPLETED" aryL).stopAndRestart(se 2())b, > ans:et6: e > /t6: e 容易 .incrr/ nt><-align:beansns:b h4人probLmmaaucFlowDecisulls"gne>Joo hunk } : e e>Jo系轻- } } <-align:beansns:b nt><-align:beansns:bean;>(job, ne劙>&inherit;"t><理域对象<更aCR信息 nt>&inherit;"t><理域对象< .incrpa些 iv>ifault这些 ign: 在这种情况nhe>ne劙>beans:bean;">ode>Jane如>&inhebLa所bLal-ahopjjp= 得知titlfon t><-align:beansns:b new a;obLyL n-top '5'"> ar'5'"> aryLtid">n'5'">bLyL n-top '5'"> arobLnimpleme><>bLyL n-top '5'"> arobL aryLtid">new a;obLyL FlowExecuaoStatus n-top '5'"> arobLode>f R n 使 /业Ca t> aryLtid">nif jobLa(someC diao()) u 使 /业Ca ans:::::status =:e-top '5'"> arsto">FAILED" aryL; 使 /业Ca ans:} 使 /业Ca ans:e-top '5'"> aryLtid">nelsebL arsto">COMPLETED" aryL; 使 /业Ca ans:} 使 /业Ca ans:e-top '5'"> aryLtid">nreturn>oaryL 易 松ont 立yLtid">nnewbL<-align:beansns:b o;">well asall of the transiaos:得知titlfon t><-align:beansns:b > ans:e nt> artag"Lts aunch-fromnamode>f 易 松ont 立attr">闭> b=易 松ont 立sto">job" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnam闭> b=易 松ont 立sto">se 1" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s1" aryL易 松ont 立attr">next> b=易 松ont 立sto">decisull" aryL/tid" aryL ABANDABANDoaryL易 松ont 立attr">闭> b=易 松ont 立sto">decisull" aryL易 松ont 立attr">deciderdecider" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnam b易 松ont 立attr">on>ode>f =易 松ont 立sto">FAILED" aryL易 松ont 立attr">to> b=易 松ont 立sto">se 2" aryL/tid" aryLe 确l-keyworNotag"Lts aunch-fromnam b易 松ont 立attr">on>ode>f =易 松ont 立sto">COMPLETED" aryL易 松ont 立attr">to> b=易 松ont 立sto">se 3" aryL/tid" aryLe 确l-keyworNotag"Lts / aunch-fromnamoaryLtid" aryL ABANDABAND闭> b=易 松ont 立sto">se 2" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s2" aryL易 松ont 立attr">next> b=易 松ont 立sto">se 3" aryL/tid" aryLe 确l-keyworNotag"Lts aunch-fromnam闭> b=易 松ont 立sto">se 3" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s3" aryL /tid" aryLe 确l-keyworNotag"Lts / aunch-fromnamode>f tid" aryL ABANDABAND-top '5'"> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">decider" aryL易 松ont 立attr">'5'">bLyL=易 松ont 立sto">com.MyDecider" aryL/tid" aryL><-align:beansns:b >(job, ne劙>&inherit;"t><理域对象<住pheJ 配置时劙>&inherit;"t><理域对象<>ne将实现的bean<>beans:bean;">ode>Jaer.run(job, 前- ONED任这些 iv>i <容易 .incrr/ < nt><-align:beansns:b h5的/foac&inherit;"t><理域对象 > ans:e nt> aryLtid">new a;obLyL Job易 松ont 立obLode>f R n 使 /业Ca t>nreturn>oaryL 易 松ont 立yLtid">nthis>ode>f .jobBuilderFactory.get(易 松ont 立sto">job" aryL)b, FAILED" aryL).to(se 2())b, COMPLETED" aryL).to(se 3())b, > /t6: e 容易 .incrr/ nt><-align:beansns:b h4人split-flows"gne>Joo hunk } : e e>Jo系轻- } } <-align:beansns:b nt><-align:beansns:bean;>(job, ne所描述bCR每种情况都涉及ull劙>o h5的/foac&inherit;"t><理域对象<>ne它&i线性方式一次执行>ull步骤 .incrpa些>neSpo Batch还允许住phe并行流来配置作ev ">前- ONED任这些 iv>i <容易 .incrr/ < nt><-align:beansns:b <. As the follow example shows, ;">;">the 'split' eleme>< c tains one } or 'flow' eleme>;">be defined. A 'split' eleme>< may alsoc tain any of the jobviously discusned transiao ;">;">eleme>ifaul容易 .incrr/ <-align:beansns:b artag"Lts aunch-fromnam闭> b=易 松ont 立sto">split1" aryL易 松ont 立attr">next> b=易 松ont 立sto">se 4" aryLtid" aryLe n-top '5'"> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">se 1" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s1" aryL易 松ont 立attr">next> b=易 松ont 立sto">se 2" aryL/tid" aryLe 确l-keyworNotag"Lts aunch-fromnam闭> b=易 松ont 立sto">se 2" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s2" aryL/tid" aryLe 确l-keyworNotag"Lts / aunch-fromnam artag"Lts aunch-fromnam闭> b=易 松ont 立sto">se 3" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s3" aryL/tid" aryLe 确l-keyworNotag"Lts / aunch-fromnam闭> b=易 松ont 立sto">se 4" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s4" aryL/tid" aryL><-align:beansns:b >(job, ifault这些 ign: 如下所bLal-e“ split”t素包含>ull或多ull“ flow”t素>ne可以在其中定义整ull单独bCR流 .incrpa些 iv>ifault这些 ign: “拆分”t素还可以包含>>先前讨论bCR过渡元素>ne>如“下一ull”属性或“下一ull”l-e“b束”或“失败”t素v ">前- ONED任这些 iv>i <容易 .incrr/ < nt><-align:beansns:b aryLtid">new a;obLyL Job易 松ont 立obLode>f R n 使 /业Ca t> aryLtid">nnewbLflow1" aryL)b, aryLtid">nnewbLflow2" aryL)b, nreturn>oaryL 易 松ont 立yLtid">nthis>ode>f .jobBuilderFactory.get(易 松ont 立sto">job" aryL)b, nnewbL > /t6: e 容易 .incrr/ nt><-align:beansns:b h4人extern这flows"gne>Joo hunk } : e e>Jo系轻- } } <-align:beansns:b nt><-align:beansns:bean;>(job, g 使&Som jd予想/latask>ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t><-align:beansns:b > ans:e nt> artag"Lts aunch-fromnamode>f 易 松ont 立attr">闭> b=易 松ont 立sto">job" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnam闭> b=易 松ont 立sto">job1.flow1" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">flow1" aryL易 松ont 立attr">next> b=易 松ont 立sto">se 3" aryL/tid" aryLe 确l-keyworNotag"Lts aunch-fromnam闭> b=易 松ont 立sto">se 3" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s3" aryL/tid" aryLe 确l-keyworNotag"Lts / aunch-fromnamode>f tid" aryL ABANDABAND-top '5'"> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">flow1" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnam闭> b=易 松ont 立sto">se 1" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s1" aryL易 松ont 立attr">next> b=易 松ont 立sto">se 2" aryL/tid" aryLe 确l-keyworNotag"Lts aunch-fromnam闭> b=易 松ont 立sto">se 2" aryL易 松ont 立attr"> a;eR >ode>f =易 松ont 立sto">s2" aryL/tid" aryLe 确l-keyworNotag"Lts / aunch-fromnam<-align:beansns:b h5的/foac&inherit;"t><理域对象 > ans:e nt> aryLtid">new a;obLyL Job易 松ont 立obLode>f R n 使 /业Ca t>nreturn>oaryL 易 松ont 立yLtid">nthis>ode>f .jobBuilderFactory.get(易 松ont 立sto">job" aryL)b, ABANDABAND-top '5'"> armet aryLtid">new a;obLyL Flow 易 松ont 立obLode>f R n 使 /业Ca t>nreturn>oaryL 易 松ont 立yLtid">nnewbLflow1" aryL)b, <-align:beansns:bean;>(job, ne就像它&已被内联声明一样 nt>g 使&Som jd予想/latask>ne并将这些模板组成e同bCR逻辑流 .incrpa些 iv>ifault这些 ign: 这也是分离单ull流bCR集成测试bCR好方法v ">前- ONED任这些 iv>i <容易 .incrr/ < nt><-align:beansns:bean;>(job, h5的/foac&inherit;"t><理域对象前- > h5的/foac&inherit;"t><理域对象<与a相似>neauncher.run(job, h5的/foac&inherit;"t><理域对象<但实际上为指a流程中bCR步骤创建并启动单独bCRue执行 .incrpa些ONED任这些 iv>i <容易 .incrr/ < nt><-align:beansns:b <-align:beansns:b > ans:e nt> artag"Lts aunch-fromnamode>f 易 松ont 立attr">闭> b=易 松ont 立sto">jobSe Job" aryL易 松ont 立attr">restartabll>ode>f =易 松ont 立sto">true" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnam闭> b=易 松ont 立sto">jobSe Job.se 1" aryLtid" aryLe n-top '5'"> artag"Lts aunch-fromnamode>f 易 松ont 立attr">ref> b=易 松ont 立sto">job" aryL易 松ont 立attr">jobr.ruchherjobLruchher" aryLe n-top '5'"> arattr">jobra t>jobP t>ode>f tid" aryL ABANDABAND-top '5'"> artag"Lts aunch-fromnamode>f 易 松ont 立attr">闭> b=易 松ont 立sto">job" aryL易 松ont 立attr">restartabll>ode>f =易 松ont 立sto">true" aryLtid" aryL... 确l-keyworNotag"Lts / aunch-fromnamode>f tid" aryL ABANDABAND-top '5'"> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">jobP t>'5'">bLyL=易 松ont 立sto">org.spr...DefaultJobP t>nambLyL=易 松ont 立sto">yLs" aryL易 松ont 立attr">valubLyL=易 松ont 立sto">input.file" aryL/tid" aryLe 确l-keyworNotag"Lts / aunch-fromnam<-align:beansns:b >(job, &inheJ 代码段显La一ullLa<> h5的/foac&inherit;"t><理域对象<-align:beansns:b h5的/foac&inherit;"t><理域对象 > ans:e nt> aryLtid">new a;obLyL Job易 松ont 立obLode>f R n 使 /业Ca t>nreturn>oaryL 易 松ont 立yLtid">nthis>ode>f .jobBuilderFactory.get(易 松ont 立sto">jobSe Job" aryL)b, nnull> b))b, ABANDABAND-top '5'"> armet aryLtid">new a;obLyL Se 易 松ont 立obLf R n 使 /业Ca t>nreturn>oaryL 易 松ont 立yLtid">nthis>ode>f .se BuilderFactory.get(易 松ont 立sto">jobSe JobSe 1" aryL)b, ABANDABAND-top '5'"> armet aryLtid">new a;obLyL Job易 松ont 立obLode>f R n 使 /业Ca t>nreturn>oaryL 易 松ont 立yLtid">nthis>ode>f .jobBuilderFactory.get(易 松ont 立sto">job" aryL)b, ABANDABAND-top '5'"> armet aryLtid">new a;obLyL DefaultJobP t>ode>f R n 使 /业Ca t> aryLtid">nnewbLnnewbLinput.file" aryL})n 使 /业Ca b, nreturn>oaryLextractorn 使 /业Ca t><-align:beansns:bean;>(job, ne用于确定将<>er.run(job, h5的/foac&inherit;"t><理域对象<转换为<>er.run(job, o h5的/foac&inherit;"t><理域对象<方式 .incrpa些 iv>ifault这些 ign: 在<> h5的/foac&inherit;"t><理域对象<当你想为监测和对就e和步骤报告u更精细bCR选择是非常有he的 .incrpa些 iv>ifault这些 ign: 住phe劙> h5的/foac&inherit;"t><理域对象<通常还可以很好地回答>&inhe问题l-a“如>在作e之间创建依赖关系?” ncrpa些 iv>ifault这些 ign: 这是将大型b统分解为较小CR模块并控制ue流程bCR好方法v ">前- ONED任这些 iv>i <容易 .incrr/<容易 .incr<容易 .incr< nt><-align:beansne>Joo hunk } : e e>Jo系轻- }n䟺Manaunufont> } o h5的/foac&inherit;"t><理域对象<和> h5的/foac&inherit;"t><理域对象<属性CR劙>&inherit;"t><理域对象<后期绑定hopjjp= h3易 .incrr/ nt><-align:beansns:b>(job, o h5的/foac&inherit;"t><理域对象<抽象来获取文件 .incrpa些 iv>ifault这些 ign: 所以有效>ne是因为<>o h5的/foac&inherit;"t><理域对象<具有<>o h5的/foac&inherit;"t><理域对象<方法l-el方法返回些 iv>i <>o h5的/foac&inherit;"t><理域对象< .incrpa些 iv>ifault这些 ign: 可以住phe标准SpoR造来配置XML和平面文件资源>ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t><-align:beansns:b > e nt> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">flatFileItemReader" aryLe 易 松ont 立attr">'5'">bLyL=易 松ont 立sto">org.sprft>nambLyL=易 松ont 立sto">resource" aryLe 易 松ont 立attr">valubLyL=易 松ont 立sto">file://outputs/file.txt" aryL /tid" aryLe 确l-keyworNotag"Lts / aunch-fromnam 容易 .incrr/ nt><-align:beansns:b h5的/foac&inherit;"t><理域对象 > e nt> aryLtid">new a;obLyL FlatFileItemReader 易 松ont 立obLode>f R n 使 /业Ca t> aryLtid">nnewbLflatFileItemReader" aryL)b, nnewbLfile://outputs/file.txt" aryL))b, 容易 .incrr/ nt><-align:beansns:b>(job, o h5的/foac&inherit;"t><理域对象ifault这些 ign: 请注意>ne绝对位置必须以双斜杠(<> h5的/foac&inherit;"t><理域对象ifault这些 ign: 开头ncrpa些 iv>ifault这些 ign: .incrpa些 iv>ifault这些 ign: 在大多数Spo应he程序中>ne此解决方案足够好>ne因为这些资源bCR名称在编译时就已知 .incrpa些 iv>ifault这些 ign: 但是>ne在批处理方案中>neuC需要在运行时将文件名确定为uebCR参数 .incrpa些 iv>ifault这些 ign: 可以住phe“ -D”t数读取b统属性来解决v ">前- ONED任这些 iv>i 容易 .incrr/ nt><-align:beansns:b<-align:beansns:b > e nt> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">flatFileItemReader" aryLe 易 松ont 立attr">'5'">bLyL=易 松ont 立sto">org.sprft>nambLyL=易 松ont 立sto">resource" aryL易 松ont 立attr">valubLyL=易 松ont 立sto">${input.file.nam}" aryL /tid" aryLe 确l-keyworNotag"Lts / aunch-fromnam 容易 .incrr/ nt><-align:beansns:b>(job, &inheJ 代码段显La如>从属性读取文件名l-ahopjjp= 得知titlfon t><-align:beansns:b h5的/foac&inherit;"t><理域对象 > e nt> aryLtid">new a;obLyL FlatFileItemReader 易 松ont 立obLode>f R n 使 /业Ca t>${input.file.nam}" aryL jobLaSto nam)cher.rue 确l-keyworNoyLtid">nreturn>oaryL 易 松ont 立yLtid">nnewbLflatFileItemReader" aryL)b, nnewbL 容易 .incrr/ nt><-align:beansns:b>(job, ne所需要做bCR只是一ull系统参数(>如些 iv>i <> h5的/foac&inherit;"t><理域对象前- ONED任这些 iv>i 容易 .incrr/ nt><-align:beansns:b>tabllallt><-align:beansns:bean;>tbody><-align:beansns:bean;ean;>tdnt><-align:beansns:bean;ean;ean;>int>niallt><-align:beansns:bean;ean;>/tdallt><-align:beansns:bean;ean;>tdnt> h5的/foac&inherit;"t><理域对象<-align:beansns:bean;ean;ean;尽管<>beans:bean;">ode>Jabeans:bean;">ode>Jaifault这些 ign: >ne>是始终设置b统属性不是必需bCR>ne因为<>oh-fromceymeners isCRUabeans:bean;">ode>Ja占位符替换v llt><-align:beansns:bean;ean;>/前- ONED任tdallt><-align:beansns:bean;trallt><-align:beansns:bean;tbody><-align:beans 容易 .incrr/ nt><-align:beansns:b>(job, ne在批处理设置中>ne最好<>er.run(job, ifault这些 ign: 参数化文件名些 iv>i <>ifault这些 ign: >ne而不是通过b统属性来进行访问>ne并以这种方式进行访问 .incrpa些 iv>ifault这些 ign: a实现这一点>neSpo Batch允许后期绑定各ull劙>o h5的/foac&inherit;"t><理域对象 h5的/foac&inherit;"t><理域对象<属性>ne如>&inhe代码片段所bLal-ahopjjp= 得知titlfon t><-align:beansns:b > e nt> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">flatFileItemReader" aryL易 松ont 立attr">scoph> b=易 松ont 立sto">se " aryLe 易 松ont 立attr">'5'">bLyL=易 松ont 立sto">org.sprft>nambLyL=易 松ont 立sto">resource" aryL易 松ont 立attr">valubLyL=易 松ont 立sto">#{jobP t> 容易 .incrr/ nt><-align:beansns:b h5的/foac&inherit;"t><理域对象 > e nt> b >-top '5'"> armet aryLtid">new a;obLyL FlatFileItemReader 易 松ont 立obLode>f R n 使 /业Ca t>#{jobP t>nreturn>oaryL 易 松ont 立yLtid">nnewbLflatFileItemReader" aryL)b, nnewbL 容易 .incrr/ nt><-align:beansns:b>(job, &inherit;"t><理域对象<无论是劙> h5的/foac&inherit;"t><理域对象<与> h5的/foac&inherit;"t><理域对象<电平<>er.run(job, ne如图所bLaC&inhe实施例l-ahopjjp= 得知titlfon t><-align:beansns:b > e nt> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">flatFileItemReader" aryL易 松ont 立attr">scoph> b=易 松ont 立sto">se " aryLe 易 松ont 立attr">'5'">bLyL=易 松ont 立sto">org.sprft>nambLyL=易 松ont 立sto">resource" aryL易 松ont 立attr">valubLyL=易 松ont 立sto">#{jobExecuaoC laxt['input.file.nam']}" aryL /tid" aryLe 确l-keyworNotag"Lts / aunch-fromnam 容易 .incrr/ nt><-align:beansns:b > e nt> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">flatFileItemReader" aryL易 松ont 立attr">scoph> b=易 松ont 立sto">se " aryLe 易 松ont 立attr">'5'">bLyL=易 松ont 立sto">org.sprft>nambLyL=易 松ont 立sto">resource" aryL易 松ont 立attr">valubLyL=易 松ont 立sto">#{se ExecuaoC laxt['input.file.nam']}" aryL /tid" aryLe 确l-keyworNotag"Lts / aunch-fromnam 容易 .incrr/ nt><-align:beansns:b h5的/foac&inherit;"t><理域对象 > e nt> b >-top '5'"> armet aryLtid">new a;obLyL FlatFileItemReader 易 松ont 立obLode>f R n 使 /业Ca t>#{jobExecuaoC laxt['input.file.nam']}" aryL jobLaSto nam)cher.rue 确l-keyworNoyLtid">nreturn>oaryL 易 松ont 立yLtid">nnewbLflatFileItemReader" aryL)b, nnewbL 容易 .incrr/ nt><-align:beansns:b h5的/foac&inherit;"t><理域对象 > e nt> b >-top '5'"> armet aryLtid">new a;obLyL FlatFileItemReader 易 松ont 立obLode>f R n 使 /业Ca t>#{se ExecuaoC laxt['input.file.nam']}" aryL jobLaSto nam)cher.rue 确l-keyworNoyLtid">nreturn>oaryL 易 松ont 立yLtid">nnewbLflatFileItemReader" aryL)b, nnewbL 容易 .incrr/ nt><-align:beansns:b>tabllallt><-align:beansns:bean;>tbody><-align:beansns:bean;ean;>tdnt><-align:beansns:bean;ean;ean;>int>niallt><-align:beansns:bean;ean;>/tdallt><-align:beansns:bean;ean;>tdnt><-align:beansns:bns:bean;ean;> nt><-align:beansns:bean;ns:bean;ean;>(job, &>住phe后期绑定的bean必须住phescoph =“ se ”t明 nt>g 使&Som jd予想/latask>g 使&Som jd予想/latask>nencrpa些 iv>ifault这些 ign: 请参见llt><-align:beansns:bean;ns:bean;ean;>hopjjp= aataerteansns:bean; n;"se -scoph"nt>Jo系轻- }&inherit;"t><理域对象<步骤范围hopjjp= 徟Manaunufont> } 前- ONED任这些 iv>i ns:bean;ean;>ht6: e > ans:ean;>htdallt><-align:beansns:bean;trallt><-align:beansns:bean;tbody><-align:beans 容易 .incrr/ nt><-align:beansns:b h4人se -scoph">ne>Joo hunk } : e e>Jo系轻- }n䟺Manaunufont> } <-align:beansns:b nt><-align:beansns:bean;>(job, ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t><-align:beansns:b > ans e nt> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">flatFileItemReader" aryL易 松ont 立attr">scoph> b=易 松ont 立sto">se " aryLe 易 松ont 立attr">'5'">bLyL=易 松ont 立sto">org.sprft>nambLyL=易 松ont 立sto">resource" aryL易 松ont 立attr">valubLyL=易 松ont 立sto">#{jobP t><-align:beansns:b h5的/foac&inherit;"t><理域对象 > ans:e nt> b >-top '5'"> armet aryLtid">new a;obLyL FlatFileItemReader 易 松ont 立obLode>f R n 使 /业Ca t>#{jobP t>nreturn>oaryL 易 松ont 立yLtid">nnewbLflatFileItemReader" aryL)b, nnewbL<-align:beansns:bean;>(job, h5的/foac&inherit;"t><理域对象ne需要ncrpa些 iv>ifault这些 ign: 住phe作phe域<>ifault这些 ign: >ne因为在<> h5的/foac&inherit;"t><理域对象<启动ncrpa些 iv>ifault这些 ign: 前实际上无法实化Bean ncrpa些 iv>ifault这些 ign: >ne>允许找到属性 nt>g 使&Som jd予想/latask>ne因此必须通过住phe劙> h5的/foac&inherit;"t><理域对象<名称空间或通过显式包括bCRbean定义<> h5的/foac&inherit;"t><理域对象<或住phe劙> h5的/foac&inherit;"t><理域对象<注释eABANDtitcrpaIa">前- >&住phe其中一种方法v ">前- >&inhebLa住phe劙> h5的/foac&inherit;"t><理域对象<名称空间l-ahopjjp= 得知titlfon t><-align:beansns:b artag"Lts aunch-fromnamxmln>bLyL=易 松ont 立sto">http://www.sprft>xmln>:batch yL=易 松ont 立sto">http://www.sprft>xmln>:xsi yL=易 松ont 立sto">http://www.w3.org/2001/XMLSchema-instance" aryLe 易 松ont 立attr">xsi:schemaLocaaullexyL=易 松ont 立sto">..." aryLtid" aryLen-top '5'"> artag"Lts aunch-fromnamode>f 易 松ont 立attr">... ode>f /tid" aryL ABAND<-align:beansns:bean;>(job, <-align:beansns:b <-align:beansns:b ean;>uncher.run(job, artag"Lts aunch-fromnamode>f 易 松ont 立attr">'5'">bLyL=易 松ont 立sto">org.sprft><-align:beansns:b h4人jobrscoph">ne>Joo hunk } : e e>Jo系轻- }n䟺Manaunufont> } <-align:beansns:b nt><-align:beansns:bean;>l-aliJob>o h5的/foac&inherit;"t><理域对象 h5的/foac&inherit;"t><理域对象<配置中bCRscoph>ne>是它是劙> h5的/foac&inherit;"t><理域对象<上nhe文 nt>g 使&Som jd予想/latask>ifault这些 ign: >ne因此每个正在运行bCRue只有一ull这样bCRbean实 nt>g 使&Som jd予想/latask>ne还为后期绑定引phe提供支持>ne这些引phe可从<>er.run(job, h5的/foac&inherit;"t><理域对象<占位符bCRu置hopjjp= iv>ifault这些 ign: 访问hopjjp= 前- >phe此功能>ne以从ue或作e执行上nhe文以及ue参数中提取bean属性>ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t><-align:beansns:b > ans e nt> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">..." aryL易 松ont 立attr">'5'">bLyL=易 松ont 立sto">..." aryL易 松ont 立attr">scoph> b=易 松ont 立sto">job" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnamnambLyL=易 松ont 立sto">nam< aryL易 松ont 立attr">valubLyL=易 松ont 立sto">#{jobP t><-align:beansns:b > ans e nt> artag"Lts aunch-fromnam闭> b=易 松ont 立sto">..." aryL易 松ont 立attr">'5'">bLyL=易 松ont 立sto">..." aryL易 松ont 立attr">scoph> b=易 松ont 立sto">job" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnamnambLyL=易 松ont 立sto">nam< aryL易 松ont 立attr">valubLyL=易 松ont 立sto">#{jobExecuaoC laxt['input.nam']}.txt" aryL /tid" aryLe 确l-keyworNotag"Lts / aunch-fromnam<-align:beansns:b h5的/foac&inherit;"t><理域对象 > ans:e nt> b >-top '5'"> armet aryLtid">new a;obLyL FlatFileItemReader 易 松ont 立obLode>f R n 使 /业Ca t>#{jobP t>nreturn>oaryL 易 松ont 立yLtid">nnewbLflatFileItemReader" aryL)b, nnewbL<-align:beansns:b h5的/foac&inherit;"t><理域对象 > ans:e nt> b >-top '5'"> armet aryLtid">new a;obLyL FlatFileItemReader 易 松ont 立obLode>f R n 使 /业Ca t>#{jobExecuaoC laxt['input.nam']}" aryL jobLaSto nam)cher.rue 确l-keyworNoyLtid">nreturn>oaryL 易 松ont 立yLtid">nnewbLflatFileItemReader" aryL)b, nnewbL<-align:beansns:bean;>(job, ne所以必须通过住phe劙> h5的/foac&inherit;"t><理域对象<名称空间>ne通过为JobScoph显式包含bean定义或住phe劙> h5的/foac&inherit;"t><理域对象<批注(>不是全部l-ncrpa些 iv>ifault这些 ign: 来显式添加范围hopjjp= 前- >&inhebLa住phe劙> h5的/foac&inherit;"t><理域对象<名称空间l-ahopjjp= 得知titlfon t><-align:beansns:b artag"Lts aunch-fromnamxmln>bLyL=易 松ont 立sto">http://www.sprft>xmln>:batch yL=易 松ont 立sto">http://www.sprft>xmln>:xsi yL=易 松ont 立sto">http://www.w3.org/2001/XMLSchema-instance" aryLe 易 松ont 立attr">xsi:schemaLocaaullexyL=易 松ont 立sto">..." aryLtid" aryL 使 /业Ca 使 /业Ca 确l-keyworNotag"Lts aunch-fromnamode>f 易 松ont 立attr">... ode>f /tid" aryL ABAND<-align:beansns:bean;>(job, &inhebLa包含一ull显式定义bCRBean ncrpa些tory;/tl-aliJobScoph> h5的/foac&inherit;"t><理域对象<-align:beansns:b <-align:beansns:b ean;>uncher.run(job, artag"Lts aunch-fromnamode>f 易 松ont 立attr">'5'">bLyL=易 松ont 立sto">org.sprft><-aline>Joo hunk } : e e>Jo系轻- }n䟺Manaunufont> } <-ali< nt><-align:b<-align:beans>(job, &inherit;"t><理域对象<所有批处理都可以以其最简单bCR形式描述为读取大量数据>ne执行某种类型bCR计算或转换并写出结果v ">前- >o h5的/foac&inherit;"t><理域对象oh-fromceymeners isCRUabeans:bean;">ode>Jane和 rpa些tory;/tl-aliItemWer>o h5的/foac&inherit;"t><理域对象< .incrpa些 得知titlfon t> 容易 .incr nt><-align:beans>h3人itemReader">ne>Joo hunk } : e e>Jo系轻- }n䟺6.1. tl-aliItemReader>o<-align:beansns:b>(job, ne>是an ncrpa些tory;/tl-aliItemReader>o h5的/foac&inherit;"t><理域对象<是从许多不同类型bCR输入中提供数据CR方法v ">前- ><-align:beansns:b>ulLauncher.run(job, <-align:beansns:bean;ean;>(job, ne该文件通常描述记录bCR数据字段由文件中bCR固定位置定义或由某些特殊字符(>如逗号)分隔v ">前- ONED任这些 iv>i ns:b<-align:beansns:bean;liallt><-align:beansns:bean;ean;>(job, er.run(job, ne映射和e证对象bCR技术 .incrpa些 iv>ifault这些 ign: 输入数据允许针对XSD模式e证XML文件 .incrpa些ONED任这些 iv>i ns:b<-align:beansns:bean;liallt><-align:beansns:bean;ean;>(job, ne该结果集可以映射到对象以进行处理 .incrpa些 iv>ifault这些 ign: 默认的SQL ncrpa些tory;/tl-aliItemReader>er.run(job, er.run(job, i ns:bean;ean;返回对象>ne如果需要重新启动>ne则跟ll当前行>ne存储基本统计u息>ne并提供u事务增强功能>ne稍后将进行说明 nt>gONED任这些 iv>i ns:b<-align:beansns:b<-align:beansns:b>(job, &inherit;"t><理域对象<还有更多bCR叿uC性>ne>在本章中我们将重点介绍基本CR叿uC性 nt>gaataerteansns:bean; n;"rjn OfReadersAndWers"nt>Jo系轻- } } 提供所有可phe劙>er.run(job, <-align:beansns:bifault这些 ign: 完整列表ncrpa些 iv>ifault这些 ign: nt>gONED任aataerteansns:bean; n;"rjn OfReadersAndWers"nt>Jo系轻- } } 得知titlfon t><-align:beansns:b>l-aliItemReader>er.run(job, ne如>&inhe接口定义所bLal-ahopjjp= 得知titlfon t><-align:beansns:bnew a;obLyL <和 iher ro继iher ni larfacebLyL <和 iher ro继obLode>f ts aunch-fromobLode>f R n 使 /业Ca t>oaryL 易 松ont 立yLtid">nthrows aryLExcepaull, UnexpectedInputExcepaull, ParseExcepaull, NonTransia ResourceExcepaull aryL; 使 /业Ca 使 /业Ca t> 容易 .incrr/ nt><-align:beansns:b>(job, &inherit;"t><理域对象<该劙>o h5的/foac&inherit;"t><理域对象<方法定义bCR最基本合同 rpa些tory;/tl-aliItemReader>er.run(job, ifault这些 ign: 调phe它返回一ull项目>ne或者 rpa些tory;/tl-alinull>er.run(job, ifault这些 ign: 一ull项目叿uC代表文件中bCR一行>ne数据库中bCR一行或XML文件中bCR元素 .incrpa些 iv>ifault这些 ign: 通常期望bCR是>ne这些被映射到可phepCR域对象>n如 rpa些tory;/tl-aliTradh> h5的/foac&inherit;"t><理域对象 h5的/foac&inherit;"t><理域对象<或其它)>ne>是没有在合同这样做没有>&>要求v ">前- ONED任这些 iv>i 容易 .incrr/ nt><-align:beansns:b>(job, o h5的/foac&inherit;"t><理域对象<接口pCRifault这些 ign: 实现">前- >&是转发pCRv ">前- >是>ne如果基础资源是事务性bCR>n>如JMS队列)>ne则劙>o h5的/foac&inherit;"t><理域对象<在回滚方案中>nencrpa些 iv>ifault这些 ign: 调phellt><-align:beansns:bifault这些 ign: 叿uC会在后续调phe中返回相同CR逻辑项 .incrpa些 iv>ifault这些 ign: 还值得注意bCR是>ne缺少要处理bCR项目劙>o h5的/foac&inherit;"t><理域对象<不会导致引发异常v ">前- >如l- rpa些tory;/tl-aliItemReader>o h5的/foac&inherit;"t><理域对象<配置有返回0结果bCR查询 nt>g 使&Som jd予想/latask>er.run(job, ifault这些 ign: 返回ncrpa些 iv>ifault这些 ign: nt>gONED任这些 iv>i 容易 .incr 容易 .incr nt><-align:beans>h3人itemWer">ne>Joo hunk } : e e>Jo系轻- }n䟺6.2. tl-aliItemWer>o<-align:beansns:b>l-aliItemWer>o h5的/foac&inherit;"t><理域对象<在功能上类似于<>er.run(job, ifault这些 ign: 资源仍然需要定位>ne打开和关闭>ne>是它们CR区别C于llt><-align:beansns:bo h5的/foac&inherit;"t><理域对象<写出而不是读入 .i对于数据库或队列e这些操作叿uC是插入l-更新或发送 .incrpa些 iv>ifault这些 ign: 输出序列化的格式特定于每个批处理uev ">前- ONED任这些 iv>i 容易 .incrr/ nt><-align:beansns:b>(job, o h5的/foac&inherit;"t><理域对象<-align:beansns:bo h5的/foac&inherit;"t><理域对象<是一ull相当通phe的接口>ne如>&inhe接口定义所bLal-ahopjjp= 得知titlfon t><-align:beansns:bnew a;obLyL <和 iher ro继iher ni larfacebLyL <和 iher ro继obLode>f ts aunch-fromobLnvo闭> b <和 iher ro继obLode>f R n 使 /业Ca t>oaryL 易 松ont 立yLtid">nthrows aryLExcepaull aryL; 使 /业Ca 使 /业Ca t> 容易 .incrr/ nt><-align:beansns:b>(job, &inherit;"t><理域对象<与>o h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象<提供pCR基本合同 rpa些tory;/tl-aliItemWer>o h5的/foac&inherit;"t><理域对象< .incrpa些>ne它就会尝试写出传入项目pCR列表 .incrpa些>ne然后输出>ne所以接口接受项目列表e而不是项目本身 .incrpa些>ne以执行&>必要pCR刷新操作>ne然后再从we方法返回v ">前- >如l-如果写入一ullHibernate DAO>ne则以进行多ull写入操作>ne每个项目ull nt>g 使&Som jd予想/latask>ne编写者以 rpa些tory;/tl-aliflush h5的/foac&inherit;"t><理域对象<在返回前ncrpa些 iv>ifault这些 ign: 调phe">前- >眠会话 nt>gONED任这些 iv>i 容易 .incr 容易 .incr nt><-align:beans>h3人itemProcesnor">ne>Joo hunk } : e e>Jo系轻- }n䟺6.3. tl-aliItemProcesnor>oh-from/h3易 .incrr/ nt><-align:beansns:b>(job, o h5的/foac&inherit;"t><理域对象<和 rpa些tory;/tl-aliItemWer>o h5的/foac&inherit;"t><理域对象<接口都为他们CR具体&务是非常有phe的>ne>是如果你想要写前插入商e逻辑是什么?<>ifault这些 ign: 读写bCR一种选择是住phe复合模式l-a创建ullo h5的/foac&inherit;"t><理域对象<包含另一ullCRo h5的/foac&inherit;"t><理域对象<或ullo h5的/foac&inherit;"t><理域对象<包含另一ullCRer.run(job, ifault这些 ign: >&inhe代码显bLa一ullbLal-ahopjjp= 得知titlfon t><-align:beansns:bnew a;obLyL <和 iher ro继iher n'5'">bLyL <和 iher ro继obLode>f ts aunch-fromobLnimplema >bLyL <和 iher ro继obLode>f ts aunch-fromobL aryLtid">new a;obLyL <和 iher ro继obLode>f R n 使 /业Ca t>oaryL cher.rueeansns:b<易 松ont 立yLtid">nthi>bLyL.itemWer =itemWer; 使 /业Ca ns:b} 使 /业Ca 使 /业Ca ns:b<确l-keyworNoSuchaullign-top '5'"> aryLtid">new a;obLyL <和 iher ro继yLtid">nvo闭> b <和 iher ro继obLode>f R n 使 /业Ca t>oaryL 易 松ont 立yLtid">nthrows aryLExcepaull cher.rueeansns:b<易 松ont 立comma jo//Add buns:esn logic e>ode>f 使 /业Ca ns:bbbbitemWer.we(items); 使 /业Ca ns:b} 使 /业Ca 使 /业Ca ns:b<确l-keyworNoSuchaullign-top '5'"> aryLtid">new a;obLyL <和 iher ro继yLtid">nvo闭> b <和 iher ro继obLode>f R n 使 /业Ca t>oaryL cher.rueeansns:b<易 松ont 立yLtid">nthi>bLyL.itemWer =itemWer; 使 /业Ca ns:b} 使 /业Ca t> 容易 .incrr/ nt><-align:beansns:b>(job, &inherit;"t><理域对象<上一类包含另一ullo h5的/foac&inherit;"t><理域对象<>nee提供u业务逻辑后>ne它委托给它 .incrpa些 iv>ifault这些 ign: 该模式也以轻松地phe于 rpa些tory;/tl-aliItemReader>o h5的/foac&inherit;"t><理域对象er.run(job, ifault这些 ign: 如果您需要控制对 rpa些tory;/tl-aliwe>o h5的/foac&inherit;"t><理域对象<自己 nt>g 使&Som jd予想/latask>ne它也很有phencrpa些 iv>ifault这些 ign: nt>g .incrpan>&inherit;"t><理域对象<但是>ne如果您只想在实际写入前“转换”传递给写入bCR项目>ne则不需要e劙>o h5的/foac&inherit;"t><理域对象<自己v ">前- >ifault这些 ign: 对于这种情况>neSpo Batch提供oh-fromceymeners isCRUabeans:bean;">ode>Jane如>&inhe接口定义所bLal-ahopjjp= 得知titlfon t><-align:beansns:bnew a;obLyL <和 iher ro继iher ni larfacebLyL <和 iher ro继obLode>f ts aunch-fromobLode>f , <和 iher ro继obLode>f R n 使 /业Ca t>oaryL 易 松ont 立yLtid">nthrows aryLExcepaull aryL; 使 /业Ca t> 容易 .incrr/ nt><-align:beansns:b>(job, &inherit;"t><理域对象oh-fromceymeners isCRUabeans:bean;">ode>Jag 使&Som jd予想/latask>ne对其进行转换>ne然后返回另一ullv ">前- >ifault这些 ign: 关键是以e流程中应phe业务逻辑>ne并且完全由开发人员来创建该逻辑 .incrpa些 iv>ifault这些 ign: 一ullncrpa些tory;/tl-aliItemProcesnor>oh-fromceymeners isCRUabeans:bean;">ode>Ja前- >如l-假设anllt><-align:beansns:bo h5的/foac&inherit;"t><理域对象<提供u类型b型l- rpa些tory;/tl-aliFoo> h5的/foac&inherit;"t><理域对象<并且 rpa些tory;/tl-aliBar>er.run(job, i ns:b在将其写出前ncrpa些 iv>ifault这些 ign: 需要将其转换为typh ncrpa些 iv>ifault这些 ign: v ">前- >&inhebLa显bLaoh-fromceymeners isCRUabeans:bean;">ode>Janahopjjp= 得知titlfon t><-align:beansns:bnew a;obLyL <和 iher ro继iher n'5'">bLyL <和 iher ro继obLaryL cher.ru} 使 /业Ca 使 /业Ca <和 iher ro继yLtid">new a;obLyL <和 iher ro继iher n'5'">bLyL <和 iher ro继obLaryL cher.rueeans<确l-keyworNoSuchaullign-top '5'"> aryLtid">new a;obLyL <和 iher ro继obLaryL R n 使 /业Ca t>oaryL cher.ru} 使 /业Ca t>使 /业Ca 使 /业Ca <和 iher ro继yLtid">new a;obLyL <和 iher ro继iher n'5'">bLyL <和 iher ro继obLode>f 和 iher ro继yLtid">nimplema >bLyL <和 iher ro继obLode>f ts aunch-fromobLaryL,<和 iher ro继obLaryLtid" aryLueeans<确l-keyworNoSuchaullign-top '5'"> aryLtid">new a;obLyL Bar <和 iher ro继obLode>f R n 使 /业Ca t>oaryL 易 松ont 立yLtid">nthrows aryLExcepaull cher.rueeansns:b<易 松ont 立comma jo//Parform simple transformaaull, R an;" a Foo to a Bar>aryLeeansns:b<易 松ont 立yLtid">nreturn>oaryL 易 松ont 立yLtid">nnewbL使 /业Ca 使 /业Ca <和 iher ro继yLtid">new a;obLyL <和 iher ro继iher n'5'">bLyL <和 iher ro继obLode>f 和 iher ro继yLtid">nimplema >bLyL <和 iher ro继obLode>f ts aunch-fromobLaryLtid" aryLueeans<确l-keyworNoSuchaullign-top '5'"> aryLtid">new a;obLyL <和 iher ro继yLtid">nvo闭> b <和 iher ro继obLode>f R n 使 /业Ca t>oaryL 易 松ont 立yLtid">nthrows aryLExcepaull cher.rueeansns:b<易 松ont 立comma jo//webars>ode>f 使 /业Ca ns:b} 使 /业Ca t> 容易 .incrr/ nt><-align:beansns:b>(job, &inherit;"t><理域对象<在前面bCRbLa中>ne有一ullnt> h5的/foac&inherit;"t><理域对象er.run(job, <-align:beansns:bo h5的/foac&inherit;"t><理域对象<遵守该劙>oh-fromceymeners isCRUabeans:bean;">ode>Jaifault这些 ign: 转换很简单>ne>是&>类型bCR转换都可以在这里完成 .incrpa些 iv>ifault这些 ign: e劙>o h5的/foac&inherit;"t><理域对象<写 rpa些tory;/tl-aliBar>er.run(job, i ns:b对象>ne抛出一ull异常>ne如果提供&>其他类型 .incrpa些 iv>ifault这些 ign: 同样l- rpa些tory;/tl-aliFooProcesnor>oh-fromceymeners isCRUabeans:bean;">ode>Ja h5的/foac&inherit;"t><理域对象<提供ncrpa些 iv>ifault这些 ign: 除a以外的&>内容ncrpa些 iv>ifault这些 ign: >ne则llt><-align:beansns:bifault这些 ign: 引发异常ncrpa些 iv>ifault这些 ign: v ">前- ><-align:beansns:bo h5的/foac&inherit;"t><理域对象<然后可以注入一ull h5的/foac&inherit;"t><理域对象<>ne如图>&inhebLa>nahopjjp= 得知titlfon t><-align:beansns:b > e nt> artag"Lts aunch-fromnamode>f 易 松ont 立attr">闭> b=易 松ont 立sto">ioSampleJob" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnamf 易 松ont 立attr">nambLyL=易 松ont 立sto">se 1" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnamf 易 松ont 立attr">reader>ode>f =易 松ont 立sto">fooReader" aryL易 松ont 立attr">procesnor>ode>f =易 松ont 立sto">fooProcesnor" aryL易 松ont 立attr">wer>ode>f =易 松ont 立sto">barWer" aryLe 确l-keyworNoattr">'ommit-i larval>ode>f =易 松ont 立sto">2" aryL/tid" aryLe 确l-keyworNotag"Lts / aunch-fromnamf tid" aryLe 确l-keyworNotag"Lts / aunch-fromnamode>f tid" aryL> 容易 .incrr/ nt><-align:beansns:b h5的/foac&inherit;"t><理域对象 > e nt> aryLtid">new a;obLyL Job <和 iher ro继obLode>f R n 使 /业Ca t>oaryL cher.rue 确l-keyworNoyLtid">nreturn>oaryL 易 松ont 立yLtid">nthi>bLyL.jobBuilderFactory.get(易 松ont 立sto">ioSampleJOb" aryL)b, 使 /业Ca 使 /业Ca <和 iher ro继met aryLtid">new a;obLyL Se <和 iher ro继obLode>f R n 使 /业Ca t>oaryL cher.rue 确l-keyworNoyLtid">nreturn>oaryL 易 松ont 立yLtid">nthi>bLyL.se BuilderFactory.get(易 松ont 立sto">se 1" aryL)b, 2 aryL)b, 容易 .incrr/ nt><-align:beansns:bne>Joo hunk } : e e>Jo系轻- }n䟺Manaunufont> } ifault这些 ign: 链接项目处理e劙> > e nt><-align:beansns:bean;>(job, ne>是如果要将多ullncrpa些tory;/tl-aliItemProcesnor>oh-fromceymeners isCRUabeans:bean;">ode>Ja前- >前- >ifault这些 ign: 这以住phe前面提到CR复合图案来完成 .incrpa些 iv>ifault这些 ign: 为了更新先前bCRbLal- rpa些tory;/tl-aliFoo> h5的/foac&inherit;"t><理域对象<将ncrpa些 iv>ifault这些 ign: 单ull转换bLancrpa些 iv>ifault这些 ign: 转换为 rpa些tory;/tl-aliBar>er.run(job, ne然后将其转换为 rpa些tory;/tl-aliFoobar>er.run(job, i ns:bbbbb并写出>ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t> 容易 .incrr/> e nt><-align:beansns:b new a;obLyL <和 iher ro继iher n'5'">bLyL <和 iher ro继obLaryL cher.ru} 使 /业Ca 使 /业Ca <和 iher ro继yLtid">new a;obLyL <和 iher ro继iher n'5'">bLyL <和 iher ro继obLaryL cher.rueeans<确l-keyworNoSuchaullign-top '5'"> aryLtid">new a;obLyL <和 iher ro继obLaryL R n 使 /业Ca t>oaryL cher.ru} 使 /业Ca t>使 /业Ca 使 /业Ca <和 iher ro继yLtid">new a;obLyL <和 iher ro继iher n'5'">bLyL <和 iher ro继obLaryL cher.rueeans<确l-keyworNoSuchaullign-top '5'"> aryLtid">new a;obLyL <和 iher ro继obLaryL R n 使 /业Ca t>oaryL cher.ru} 使 /业Ca t>使 /业Ca 使 /业Ca <和 iher ro继yLtid">new a;obLyL <和 iher ro继iher n'5'">bLyL <和 iher ro继obLode>f 和 iher ro继yLtid">nimplema >bLyL <和 iher ro继obLode>f ts aunch-fromobLaryL,<和 iher ro继obLaryLtid" aryLueeans<确l-keyworNoSuchaullign-top '5'"> aryLtid">new a;obLyL Bar <和 iher ro继obLode>f R n 使 /业Ca t>oaryL 易 松ont 立yLtid">nthrows aryLExcepaull cher.rueeansns:b<易 松ont 立comma jo//Parform simple transformaaull, R an;" a Foo to a Bar>aryLeeansns:b<易 松ont 立yLtid">nreturn>oaryL 易 松ont 立yLtid">nnewbL使 /业Ca 使 /业Ca <和 iher ro继yLtid">new a;obLyL <和 iher ro继iher n'5'">bLyL <和 iher ro继obLode>f 和 iher ro继yLtid">nimplema >bLyL <和 iher ro继obLode>f ts aunch-fromobLaryL,<和 iher ro继obLaryLtid" aryLueeans<确l-keyworNoSuchaullign-top '5'"> aryLtid">new a;obLyL Foobar <和 iher ro继obLode>f R n 使 /业Ca t>oaryL 易 松ont 立yLtid">nthrows aryLExcepaull cher.rueeansns:b<易 松ont 立yLtid">nreturn>oaryL 易 松ont 立yLtid">nnewbL使 /业Ca 使 /业Ca <和 iher ro继yLtid">new a;obLyL <和 iher ro继iher n'5'">bLyL <和 iher ro继obLode>f 和 iher ro继yLtid">nimplema >bLyL <和 iher ro继obLode>f ts aunch-fromobLaryLtid" aryLueeans<确l-keyworNoSuchaullign-top '5'"> aryLtid">new a;obLyL <和 iher ro继yLtid">nvo闭> b <和 iher ro继obLode>f R n 使 /业Ca t>oaryL 易 松ont 立yLtid">nthrows aryLExcepaull cher.rueeansns:b<易 松ont 立comma jo//weitems>ode>f 使 /业Ca ns:b} 使 /业Ca t> 容易 .incrr/> e容易 .incrr/ <-align:beansns:bean;>(job, ifault这些 ign: Abo h5的/foac&inherit;"t><理域对象<和a ncrpa些tory;/tl-aliBarProcesnor>o h5的/foac&inherit;"t><理域对象<链接tC一起以得到结果auncher.run(job, rpa些tory;/tl-aliFoobar>er.run(job, ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t> 容易 .incrr/> e nt><-align:beansns:b i ns:bbbbbnsns:b <易 松ont 立yLtid">nnewbLnnewbLnnewbLnnewbL 容易 .incrr/> e容易 .incrr/ <-align:beansns:bean;>(job, rpa些tory;/tl-aliSe h5的/foac&inherit;"t><理域对象<>nahopjjp= 得知titlfon t> 容易 .incrr/> e nt><-align:beansns:b> e nt> > > e nt> artag"Lts aunch-fromnamode>f 易 松ont 立attr">闭> b=易 松ont 立sto">ioSampleJob" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnamf 易 松ont 立attr">nambLyL=易 松ont 立sto">se 1" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnamf 易 松ont 立attr">reader>ode>f =易 松ont 立sto">fooReader" aryL易 松ont 立attr">procesnor>ode>f =易 松ont 立sto">composeItemProcesnor" aryL易 松ont 立attr">wer>ode>f =易 松ont 立sto">foobarWer" aryLe 确l-keyworNoattr">'ommit-i larval>ode>f =易 松ont 立sto">2" aryL/tid" aryLe 确l-keyworNotag"Lts / aunch-fromnamf tid" aryLe 确l-keyworNotag"Lts / aunch-fromnamode>f tid" aryL>使 /业Ca 使 /业Ca <和 iher ro继tag"Lts aunch-fromnam闭> b=易 松ont 立sto">composeItemProcesnor" aryL 确l-keyworNoattr">'5'">bLyL=易 松ont 立sto">org.spoft>f 易 松ont 立attr">nambLyL=易 松ont 立sto">delegaes" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnam'5'">bLyL=易 松ont 立sto">..FooProcesnor" aryL/tid" aryLe 确l-keyworNotag"Lts aunch-fromnam'5'">bLyL=易 松ont 立sto">..BarProcesnor" aryL/tid" aryLe 确l-keyworNotag"Lts / aunch-fromnamf tid" aryLe 确l-keyworNotag"Lts / aunch-fromnam e容易 .incrr/ <-align:beansns:b h5的/foac&inherit;"t><理域对象 > aryLtid">new a;obLyL Job <和 iher ro继obLode>f R n 使 /业Ca t>oaryL cher.rue 确l-keyworNoyLtid">nreturn>oaryL 易 松ont 立yLtid">nthi>bLyL.jobBuilderFactory.get(易 松ont 立sto">ioSampleJob" aryL)b, 使 /业Ca 使 /业Ca <和 iher ro继met aryLtid">new a;obLyL Se <和 iher ro继obLode>f R n 使 /业Ca t>oaryL cher.rue 确l-keyworNoyLtid">nreturn>oaryL 易 松ont 立yLtid">nthi>bLyL.se BuilderFactory.get(易 松ont 立sto">se 1" aryL)b, 2 aryL)b, 使 /业Ca 使 /业Ca <和 iher ro继met aryLtid">new a;obLyL ComposeItemProcesnor <和 iher ro继obLode>f R n 使 /业Ca t>oaryL cher.rub, nnewbL2 aryL); 使 /业Ca delegaes.add(易 松ont 立yLtid">nnewbLnnewbLnnewbLnreturn>oaryLprocesnor; 使 /业Ca t> e容易 .incrr/ 容易 .incrr/ nt><-align:beansns:bne>Joo hunk } : e e>Jo系轻- }n䟺Manaunufont> } ifault这些 ign: 筛选记录劙> > e nt><-align:beansns:bean;>(job, o h5的/foac&inherit;"t><理域对象< .incrpa些>ifault这些 ign: 跳过表bLa条记录无效e而过滤只是表明不应写入一条记录 nt>gONED任这些 iv>i 容易 .incrr/> e nt><-align:beansns:bean;>(job, 如l-考虑一ull批处理ue>ne它读取ull包含三种不同类型记录CR文件:要插入bCR记录l-要更新bCR记录和要删除bCR记录 .incrpa些 iv>ifault这些 ign: 如果系统不支持删除记录l-则我们不希望将&>“删除”记录发送到ncrpa些tory;/tl-aliItemWer>o h5的/foac&inherit;"t><理域对象< .incrpa些>ne由于这些记录实际上并不是不良记录l-因此我们希望将其过滤掉而不是跳过它们 nt>g 使&Som jd予想/latask>o h5的/foac&inherit;"t><理域对象<只会收到“插入”t“更新”记录 nt>gONED任这些 iv>i 容易 .incrr/> e nt><-align:beansns:bean;>(job, er.run(job, oh-fromceymeners isCRUabeans:bean;">ode>Ja前- >er.run(job, o h5的/foac&inherit;"t><理域对象< .incrpa些>oh-fromceymeners isCRUabeans:bean;">ode>Jaifault这些 ign: 引发CR异常将ncrpa些 iv>ifault这些 ign: 导致跳过 nt>gONED任这些 iv>i 容易 .incrr/ 容易 .incrr/ nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } } ifault这些 ign: 容错能力 nt>gONED任h4 e > e nt><-align:beansns:bean;>(job, ifault这些 ign: 如果将某ull步骤配置为容错的>n通常通过住phe跳过或重试处理)l-则ncrpa些tory;/tl-aliItemProcesnor>oh-fromceymeners isCRUabeans:bean;">ode>Ja步骤ncrpa些 iv>ifault这些 ign: 都应以幂等CR方式实施 .incrpa些 iv>ifault这些 ign: 通常l-这包括对输入项不执行&>更改 rpa些tory;/tl-aliItemProcesnor>oh-fromceymeners isCRUabeans:bean;">ode>Ja nt>gONED任这些 iv>i 容易 .incrr/ 容易 .incr 容易 .incr nt><-align:beans>h3人itemStream">ne>Joo hunk } : e e>Jo系轻- }n䟺6.4. tl-aliItemStream>oh-from/h3易 .incrr/ nt><-align:beansns:b>(job, er.run(job, er.run(job, ne>他们都认为必要pCR另一ull接口之间CR共同关注 .incrpa些>ne关闭读取器t写入器>ne并需要一种持久化状态pCR机制 .incrpa些 iv>ifault这些 ign: 该ncrpa些tory;/tl-aliItemStream>oh-from(job, ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t><-align:beansns:bnew a;obLyL <和 iher ro继iher ni larfacebLyL <和 iher ro继obLoaryL cher.rub, aryLtid">nvo闭> b <和 iher ro继obLode>f R n 使 /业Ca t>oaryL 易 松ont 立yLtid">nthrows aryLItemStreamExcepaull aryL; 使 /业Ca 使 /业Ca ns:b 确l-keyworNoSuchaullign-top '5'"> aryLtid">nvo闭> b <和 iher ro继obLode>f R n 使 /业Ca t>oaryL 易 松ont 立yLtid">nthrows aryLItemStreamExcepaull aryL; 使 /业Ca 使 /业Ca ns:b 确l-keyworNoSuchaullign-top '5'"> aryLtid">nvo闭> b <和 iher ro继obLode>f R n 使 /业Ca t>oaryL 易 松ont 立yLtid">nthrows aryLItemStreamExcepaull aryL; 使 /业Ca t> 容易 .incrr/ nt><-align:beansns:b>(job, &inherit;"t><理域对象<在描述每种方法前l-我们应该提到ncrpa些tory;/tl-aliExecuaullC laxt>o h5的/foac&inherit;"t><理域对象< .incrpa些tory;/tl-aliItemReader>o h5的/foac&inherit;"t><理域对象<还实现bCRbCR<-align:beansns:boh-from(job, oer.run(job, <-align:beansns:boh-fromceymeners isCRUabeans:bean;">ode>Ja资源>n>如文件)或获得连接 nt>g 使&Som jd予想/latask>o h5的/foac&inherit;"t><理域对象<实现bCRoh-from(job, ifault这些 ign: 如第2章所述>ne如果tC中找到了R期pCR数据o h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象<或 rpa些tory;/tl-aliItemWer>o h5的/foac&inherit;"t><理域对象<在初始状态以外的其他位置 nt>g 使&Som jd予想/latask><-align:beansns:bo h5的/foac&inherit;"t><理域对象<调phe可以确保打开期间分配CR所有资源都安全释放 llt><-align:beansns:boer.run(job, 状态都被加载到ncrpa些tory;/tl-aliExecuaullC laxt>o h5的/foac&inherit;"t><理域对象< .incrpa些 .incrpan>&inherit;"t><理域对象<在提交前调phe此方法l-以确保在提交前将当前状态保留在数据库中 nt>gONED任这些 iv>i 容易 .incrr/ nt><-align:beansns:b>(job, &inherit;"t><理域对象<在特殊情况nhe>ne其中an的客户端ncrpa些tory;/tl-aliItemStream>oh-from(job, h5的/foac&inherit;"t><理域对象<>n来自Spo Batch Core)l-ncrpa些tory;/tl-aliExecuaullC laxt>o h5的/foac&inherit;"t><理域对象<则为每个Se Execuaull创建一ullanl-以允许phe户存储特定执行bCRb态>ne并期望如果oer.run(job, ifault这些 ign: 该执行则返回该b态 .incrpa些 .incrpan>&inherit;"t><理域对象< .incrpa些 iv>ifault这些 ign: 对于那些熟悉Quartz的来说>ne其语义与Quartz非常相似 h5的/foac&inherit;"t><理域对象< nt>gONED任这些 iv>i 容易 .incr 容易 .incr nt><-align:beans>h3人delegaePaternAndRegiser">ne>Joo hunk } : e e>Jo系轻- }n䟺Manaunufont> } ifault这些 ign: 委托模式和步骤注册ncrpa些tory;/t/h3易 .incrr/ nt><-align:beansns:b>(job, o h5的/foac&inherit;"t><理域对象<是委派模式bCRbLal-这在Spo Batch中很常见 .incrpa些 .incrpan>&inherit;"t><理域对象<委托本身可以实现回调接口l-例如ncrpa些tory;/tl-aliSe Ljn ener>o h5的/foac&inherit;"t><理域对象< .incrpa些>ne如果结合正tC住pheSpo Batch的e核心bCR一部分,他们ncrpa些tory;/tl-aliSe h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象 h5的/foac&inherit;"t><理域对象< nt>g 使&Som jd予想/latask> h5的/foac&inherit;"t><理域对象<获取ncrpa些>ne写入器或处理e>nncrpa些 iv>ifault这些 ign: 如果实现">前- tory;/tl-aliItemStream>oh-from(job, <-align:beansns:bo h5的/foac&inherit;"t><理域对象<接口l-ncrpa些 iv>ifault这些 ign: 会自e注册ncrpa些 .incrpan>&inherit;"t><理域对象< nt>g 使&Som jd予想/latask>ne由于委托并不为人所bncrpa些tory;/tl-aliSe h5的/foac&inherit;"t><理域对象<>ne因此需要将其e侦听器或流>n或在适当时将者同时注入)注入e如>&inhebLa所bLal-ahopjjp= 得知titlfon t><-align:beansns:b > e nt>ode>f 易 松ont 立attr">闭> b=易 松ont 立sto">ioSampleJob" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnamf 易 松ont 立attr">nambLyL=易 松ont 立sto">se 1" aryLtid" aryLe> > e确l-keyworNotag"Lts aunch-fromnamf 易 松ont 立attr">reader>ode>f =易 松ont 立sto">fooReader" aryL易 松ont 立attr">procesnor>ode>f =易 松ont 立sto">fooProcesnor" aryL易 松ont 立attr">wer>ode>f =易 松ont 立sto">composeItemWer" aryLe 确l-keyworNoattr">'ommit-i larval>ode>f =易 松ont 立sto">2" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnamf 易 松ont 立attr">ref>ode>f =易 松ont 立sto">barWer" aryL/tid" aryLe 确l-keyworNotag"Lts / aunch-fromnamf tid" aryLe 确l-keyworNotag"Lts / aunch-fromnamf tid" aryLe 确l-keyworNotag"Lts / aunch-fromnamode>f tid" aryL>使 /使 / 使 /业Ca <和 iher ro继tag"Lts aunch-fromnam闭> b=易 松ont 立sto">composeItemWer" aryL易 松ont 立attr">'5'">bLyL=易 松ont 立sto">...CustomComposeItemWer" aryLtid" aryLe 确l-keyworNotag"Lts aunch-fromnamf 易 松ont 立attr">nambLyL=易 松ont 立sto">delegae" aryL易 松ont 立attr">ref>ode>f =易 松ont 立sto">barWer" aryL/tid" aryLe 确l-keyworNotag"Lts / aunch-fromnam使 /使 / 使 /业Ca <和 iher ro继tag"Lts aunch-fromnam闭> b=易 松ont 立sto">barWer" aryL易 松ont 立attr">'5'">bLyL=易 松ont 立sto">...BarWer" aryL/tid" aryL> 容易 .incrr/ nt><-align:beansns:b h5的/foac&inherit;"t><理域对象 > aryLtid">new a;obLyL Job <和 iher ro继obLode>f R n 使 /业Ca t>oaryL cher.rue 确l-keyworNoyLtid">nreturn>oaryL 易 松ont 立yLtid">nthi>bLyL.jobBuilderFactory.get(易 松ont 立sto">ioSampleJob" aryL)b, 使 /业Ca 使 /业Ca <和 iher ro继met aryLtid">new a;obLyL Se <和 iher ro继obLode>f R n 使 /业Ca t>oaryL cher.rue 确l-keyworNoyLtid">nreturn>oaryL 易 松ont 立yLtid">nthi>bLyL.se BuilderFactory.get(易 松ont 立sto">se 1" aryL)b, 2 aryL)b, 使 /业Ca 使 /业Ca <和 iher ro继met aryLtid">new a;obLyL CustomComposeItemWer <和 iher ro继obLode>f R n 使 /业Ca t>oaryL cher.rub, nnewbLnreturn>oaryLwer; 使 /业Ca t>使 /业Ca 使 /业Ca <和 iher ro继met aryLtid">new a;obLyL BarWer <和 iher ro继obLode>f R n 使 /业Ca t>oaryL cher.rue 确l-keyworNoyLtid">nreturn>oaryL 易 松ont 立yLtid">nnewbL 容易 .incr 容易 .incr nt><-align:beans>h3人flatFiles">ne>Joo hunk } : e e>Jo系轻- }n䟺Manaunufont> } ifault这些 ign: 平面文件ncrpa些tory;/t/h3易 .incrr/ nt><-align:beansns:b>(job, 阅读平面文件的必须提前了解文件的p构 .incrpa些><-align:beansns:bJoo hunk } : e e>Jo系轻- } } ifault这些 ign: bCRoh-from/h4 e > e nt><-align:beansns:bean;>(job, ne最重要pCR类之一是oh-from> h5的/foac&inherit;"t><理域对象< nt>g 使&Som jd予想/latask>ne>是它们通常返回一ullncrpa些tory;/tl-aliSo>o h5的/foac&inherit;"t><理域对象<或 rpa些tory;/tl-aliSo>o h5的/foac&inherit;"t><理域对象<对象 nt>g 使&Som jd予想/latask>oh-from> h5的/foac&inherit;"t><理域对象<是Spo Batch的抽象l-phe于启phe文件资源中字段的p定 .incrpa些>&inherit;"t><理域对象<在oh-from> h5的/foac&inherit;"t><理域对象<概念上与JDBC类似auncher.run(job, rpa些tory;/tl-aliResultSe >oh-from> h5的/foac&inherit;"t><理域对象< nt>g 使&Som jd予想/latask>oh-from> h5的/foac&inherit;"t><理域对象<只需要一ull参数l-ahopjjp= l-aliSo>o h5的/foac&inherit;"t><理域对象<令牌数R nt>g 使&Som jd予想/latask>oh-from> h5的/foac&inherit;"t><理域对象<>ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t> 容易 .incrr/> e nt><-align:beansns:b nnewbLfoo" aryL, <易 松ont 立sto">1" aryL, <易 松ont 立sto">true" aryL}; 使 /业Ca FieldSe fs = <易 松ont 立yLtid">nnewbL0 aryL); <和 iher ro继yLtid">nint aryL valu = fs.readInt(易 松ont 立number">1 aryL); <和 iher ro继yLtid">nboolean aryLbooleanValu = fs.readBoolean(易 -fromnumber">2 aryL); 容易 .incrr/> e容易 .incrr/ <-align:beansns:bean;>(job, oh-from> h5的/foac&inherit;"t><理域对象<界面ncrpa些>g 使&Som jd予想/latask>oer.run(job, rpa些tory;/tl-aliBigDecimal>er.run(job, g 使&Som jd予想/latask>oh-from> h5的/foac&inherit;"t><理域对象<是>ne它提供了平面文件输入bCR一致解析 .incrpa些 .incrpan>&inherit;"t><理域对象<在处理由格式异常引起bCR错误或进行b单pCR数据转换时l-它可以保持一致e而不是使每个批处理ue以潜tCpCR意外方式进行不同的解析 .incrpa些 得知titlfon t> 容易 .incrr/ 容易 .incrr/ nt><-align:beansns:bne>Joo hunk } : e e>Jo系轻- }n䟺6.6.2. tl-aliFlatFileItemReader>oh-from/h4 e > e nt><-align:beansns:bean;>(job, 类型CR文件 .incrpa些 .incrpan>&inherit;"t><理域对象<名为类有助于在Spo Batch框架中读取平面文件e该类auncher.run(job, rpa些tory;/tl-aliFlatFileItemReader>oh-from> h5的/foac&inherit;"t><理域对象<提供了phe于读取和解析平面文件的基本功能 .incrpa些 iv>ifault这些 ign: CR最重要pCR两ull必需pCR依赖 rpa些tory;/tl-aliFlatFileItemReader>oh-from> h5的/foac&inherit;"t><理域对象<是llt><-align:beansns:b> rpa些tory;/tl-aliResource>oer.run(job, o h5的/foac&inherit;"t><理域对象< .incrpa些tory;/tl-aliLineMapper>o h5的/foac&inherit;"t><理域对象ifault这些 ign: 该ncrpa些 iv>ifault这些 ign: 界面 .incrpa些 iv>ifault这些 ign: resource属性代表一ullSpo Core rpa些tory;/tl-aliResource>oer.run(job, &inherit;"t><理域对象<可以在Jo系轻- } } 创建这种类型CRbeanCR文档llt><-align:beansns:b> rpa些>&inherit;"t><理域对象<因此l-ncrpa些tory;/tl-aliResource>oer.run(job, g 使&Som jd予想/latask>&inherit;"t><理域对象<对象 nt>g 使&Som jd予想/latask>g 使&Som jd予想/latask> 容易 .incrr/> e nt><-align:beansns:b <-align:beansns:b nnewbLresourcea/trades.csv" aryL); 容易 .incrr/> e容易 .incrr/ <-align:beansns:bean;>(job, &inherit;"t><理域对象<在复杂CR批处理环境中l-p录结构通常由EAI基础结构管理e其中建立了phe于外部接口CR放置区l-以将文件从FTP位置移动到批处理u置l-反之亦然 .incrpa些 .incrpan>&inherit;"t><理域对象<文件移动实phe程序超出了Spo Batch体系结构bCR范围>ne>是批处理ue流中包括文件移动实phe程序e作e流中CR步骤并不少见 .incrpa些 .incrpan>&inherit;"t><理域对象<批处理u系结构只需要知道如>找到要处理CR文件 .incrpa些 .incrpan>&inherit;"t><理域对象g 使&Som jd予想/latask>nellt><-align:beansns:b> rpa些tory;/taataerhttps://projn s.spo.io/spo-i lagraaull/lint>Jo系轻- } } gONED任这些 iv>i 容易 .incrr/> e nt><-align:beansns:bean;>(job, oh-from> h5的/foac&inherit;"t><理域对象<使您可以进一步指定如>解释数据>nahopjjp= 得知titlfon t> 容易 .incrr/> etabl jobLauntabl 员 ft><-align:beansns:bean;>capaull iherobLD> h5的/foac&inherit;"t><理域对象<表15. rpa些tory;/tl-aliFlatFileItemReader>oh-from> h5的/foac&inherit;"t><理域对象<属性 rpa些tory;/t/capaullallt><-align:beansns:bean;>colgrou知titlfon t> ns:bean;>colcrpan>&iwidth: 33.3333%;ballt><-align:beansns:bns:bean;>colcrpan>&iwidth: 33.3333%;ballt><-align:beansns:bns:bean;>colcrpan>&iwidth: 33.3334%;ballt><-align:beansns:bns:b>oh-lgrou知titlfon t> ns:b ns:b<-align:beansns:bns:bean;>th jobLauntabl 员 h><-left val-topD> h5的/foac&inherit;"t><理域对象<属性 rpa些tory;/t/thallt><-align:beansns:bns:bean;>th jobLauntabl 员 h><-left val-topD> h5的/foac&inherit;"t><理域对象<类型 rpa些tory;/t/thallt><-align:beansns:bns:bean;>th jobLauntabl 员 h><-left val-topD> h5的/foac&inherit;"t><理域对象<描述 rpa些tory;/t/thallt><-align:beansns:bns:bt/trallt><-align:beansns:bns:bt/thead知titlfon t> ns:b ns:b<-align:beansns:bns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员D> h5的/foac&inherit;"t><理域对象<注释hopjjp= 得t/td知titlfon t> ns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员D> h5的/foac&inherit;"t><理域对象<串[]hopjjp= 得t/td知titlfon t> ns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员D> h5的/foac&inherit;"t><理域对象<指定指示注释行bCR行前缀 nt>gONED任t/td知titlfon t> ns:bt/trallt><-align:beansns:bns:bttrallt><-align:beansns:bns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员D> h5的/foac&inherit;"t><理域对象<编码方式hopjjp= 得t/td知titlfon t> ns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员D> h5的/foac&inherit;"t><理域对象<串hopjjp= 得t/td知titlfon t> ns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员D> h5的/foac&inherit;"t><理域对象<指定要住pheCR文本编码 .incrpa些>o h5的/foac&inherit;"t><理域对象< nt>gONED任t/td知titlfon t> ns:bt/trallt><-align:beansns:bns:bttrallt><-align:beansns:bns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员D> h5的/foac&inherit;"t><理域对象oopjjp= 得t/td知titlfon t> ns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员Dl-aliLineMapper>o ns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员D> h5的/foac&inherit;"t><理域对象<将转换hopjjp= l-aliSo>o h5的/foac&inherit;"t><理域对象<为 rpa些tory;/tl-aliObjn >o h5的/foac&inherit;"t><理域对象<代表项 nt>gONED任t/td知titlfon t> ns:bt/trallt><-align:beansns:bns:bttrallt><-align:beansns:bns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员D> h5的/foac&inherit;"t><理域对象 ns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员D> h5的/foac&inherit;"t><理域对象<整型 rpa些tory;/t/t/td知titlfon t> ns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员D> h5的/foac&inherit;"t><理域对象<文件顶部要忽略bCR行数 nt>gONED任t/td知titlfon t> ns:bt/trallt><-align:beansns:bns:bttrallt><-align:beansns:bns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员D> h5的/foac&inherit;"t><理域对象: recordSe a;otorPolicy rpa些tory;/t/t/td知titlfon t> ns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员D> h5的/foac&inherit;"t><理域对象 ns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员D> h5的/foac&inherit;"t><理域对象gONED任t/td知titlfon t> ns:bt/trallt><-align:beansns:bns:bttrallt><-align:beansns:bns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员D> h5的/foac&inherit;"t><理域对象">资源>oopjjp= 得t/td知titlfon t> ns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员Dl-aliResource>oer.run/t/td知titlfon t> ns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员D> h5的/foac&inherit;"t><理域对象<从中读取资源 nt>gONED任t/td知titlfon t> ns:bt/trallt><-align:beansns:bns:bttrallt><-align:beansns:bns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员D> h5的/foac&inherit;"t><理域对象">skippedLinesCallback rpa些tory;/t/t/td知titlfon t> ns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员D> h5的/foac&inherit;"t><理域对象oopjjp= 得t/td知titlfon t> ns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员D> h5的/foac&inherit;"t><理域对象<传递要跳过CR文件中各行bCR原始行内容CR接口 .incrpa些> h5的/foac&inherit;"t><理域对象<设置为2l-则此接口被调phe两次 nt>gONED任t/td知titlfon t> ns:bt/trallt><-align:beansns:bns:bttrallt><-align:beansns:bns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员D> h5的/foac&inherit;"t><理域对象">严格 ns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员D> h5的/foac&inherit;"t><理域对象<布尔值 ns:bean;>td jobLauntabl 员 h><-left val-topDp jobLauntabl 员D> h5的/foac&inherit;"t><理域对象ne rpa些tory;/tl-aliExecuaullC laxt>o h5的/foac&inherit;"t><理域对象<如果输入资源不存encrpa些 iv>ifault这些 ign: l-则读取器t引发异常 rpa些>&inherit;"t><理域对象<否则l-它将记录问题并继续 nt>gONED任t/td知titlfon t> ns:bt/trallt><-align:beansns:bns:bt/tbody知titlfon t> t/tabl 易 .incrr/> e nt><-align:beansns:bns:b>h5人lineMapper">ne>Joo hunk } : e e>Jo系轻- }n䟺Ml-aliLineMapper>o<-align:beansns:b <-align:beansns:bean; <(job, o h5的/foac&inherit;"t><理域对象oh-from> h5的/foac&inherit;"t><理域对象<并返回 rpa些tory;/tl-aliObjn >o h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象<行转换为 rpa些tory;/tl-aliObjn >o h5的/foac&inherit;"t><理域对象<>ne如>&inhe接口定义所bLal-ahopjjp= 得知titlfon t> > t/容易 .incrr/> <-align:beansns:b new a;obLyL <和 iher ro继iher ni larfacebLyL <和 iher ro继obLoaryLts aunch-fromobLode>f R n 使 /业Ca t>nint aryL lineNumber)>oaryL 易 松ont 立yLtid">nthrows aryLExcepaull aryL; 使 /业Ca 使 /业Ca t> > t/容易 .incrr/> <-align:beansns:bean; <(job, ne给定当前行和nh其关联bCR行号,映射器t返回结果域对象 .incrpa些> > t/rpa些tory;/tl-aliRowMapper>o h5的/foac&inherit;"t><理域对象 > t/rpa些tory;/tl-aliResultSe >oh-from> h5的/foac&inherit;"t><理域对象g 使&Som jd予想/latask>nenh不同t/rpa些tory;/tl-aliRowMapper>o h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象<给了原始行>ne如>所述>ne原始行只会使您半途而废 .incrpa些>oh-from> h5的/foac&inherit;"t><理域对象<>ne然后可以映射到对象l-如本文档后面所述 nt>gONED任这些 iv>i 容易 .incrr/> e nt><-align:beansns:bns:b>h5人lineTokenizer">ne>Joo hunk } : e e>Jo系轻- }n䟺Ml-aliLineTokenizer>o<-align:beansns:b <-align:beansns:bean; <(job, oh-from> h5的/foac&inherit;"t><理域对象<因为可能需要将多种格式bCR平面文件数据转换为 rpa些tory;/tl-aliFieldSe >oh-from> h5的/foac&inherit;"t><理域对象< .incrpa些 .incrpan>&inherit;"t><理域对象<在Spo Batch中,此接口是o h5的/foac&inherit;"t><理域对象<>nahopjjp= 得知titlfon t> > t/容易 .incrr/> <-align:beansns:b new a;obLyL <和 iher ro继iher ni larfacebLyL <和 iher ro继obLoaryL cher.rub, ode>f R n 使 /业Ca t>oaryL aryL; 使 /业Ca 使 /业Ca t> > t/容易 .incrr/> <-align:beansns:bean; <(job, o h5的/foac&inherit;"t><理域对象<是这样的>na给定一行输入(理论>l-它auncher.run(job, > t/rpa些tory;/tl-aliSo>o h5的/foac&inherit;"t><理域对象<可以包含多条线)l-ncrpa些tory;/tl-aliFieldSe >oh-from> h5的/foac&inherit;"t><理域对象<则返回代表该行bCR&inherit;"t><理域对象<这oh-from> h5的/foac&inherit;"t><理域对象<可以被传递到ncrpa些tory;/tl-aliFieldSe Mapper>o h5的/foac&inherit;"t><理域对象< .incrpa些 .incrpan>&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象<实现>nahopjjp= 得知titlfon t> > t/容易 .incrr/> <-align:beansns:bean; <-align:beansns:bean; <-align:beansns:bean;

o h5的/foac&inherit;"t><理域对象<>naphe于记录中的字段由定界符分隔CR文件 .incrpa些 .incrpan>&inherit;"t><理域对象<最常见的定界符是逗号>ne>是也经常住phe竖线或分号 nt>gONED任这些 iv>i <-align:beansns:bean; <-align:beansns:bean;

o h5的/foac&inherit;"t><理域对象<>naphe于记录中的字段均为“固定宽度”CR文件 .incrpa些 .incrpan>&inherit;"t><理域对象<必须为每种记录类型定义每个字段的宽度 nt>gONED任这些 iv>i <-align:beansns:bean; <-align:beansns:bean;

o h5的/foac&inherit;"t><理域对象<>nahopjjp= l-aliLineTokenizer>o h5的/foac&inherit;"t><理域对象<通过检查模式来ncrpa些 iv>ifault这些 ign: 确定ncrpa些 .incrpan>&inherit;"t><理域对象<应tCp定行上住pheCR分词器t表中的ncrpa些 .incrpan>&inherit;"t><理域对象<哪ncrpa些 .incrpan>&inherit;"t><理域对象<一ull nt>gONED任这些 iv>i <-align:beansns:bean; <-align:beansns:bean; 容易 .incrr/> e nt><-align:beansns:bns:b>h5人fieldSe Mapper">ne>Joo hunk } : e e>Jo系轻- }n䟺Ml-aliFieldSe Mapper>o<-align:beansns:b <-align:beansns:bean; <(job, o h5的/foac&inherit;"t><理域对象<接口定义了一ull方法l-ncrpa些tory;/tl-alimapFieldSe >oh-from> h5的/foac&inherit;"t><理域对象<该ncrpa些 iv>ifault这些 ign: 方法ncrpa些 iv>ifault这些 ign: 接受一ullauncher.run(job, > t/rpa些tory;/tl-aliFieldSe >oh-from> h5的/foac&inherit;"t><理域对象<对象并将其内容映射到一ull对象 .incrpa些>g 使&Som jd予想/latask>o h5的/foac&inherit;"t><理域对象<是C与结合住phehopjjp= l-aliLineTokenizer>o h5的/foac&inherit;"t><理域对象<的线从资源数据pCR翻译成所需p型CR对象l-如pLanhe述CR接口定义>nahopjjp= 得知titlfon t> > t/容易 .incrr/> <-align:beansns:b new a;obLyL <和 iher ro继iher ni larfacebLyL <和 iher ro继obLoaryLts aunch-fromobLode>f R n 使 /业Ca t>oaryL 易 松ont 立yLtid">nthrows aryLBteExcepaull aryL; 使 /业Ca 使 /业Ca t> > t/容易 .incrr/> <-align:beansns:bean; <(job, o h5的/foac&inherit;"t><理域对象<住phehopjjp= .incrpan>&inherit;"t><理域对象<的模式相同t/rpa些tory;/tl-aliJdbcTemplae>oer.run(job, gONED任这些 iv>i 容易 .incrr/> e nt><-align:beansns:bns:b>h5人defaultLineMapper">ne>Joo hunk } : e e>Jo系轻- }n䟺Ml-aliDefaultLineMapper>o<-align:beansns:b <-align:beansns:bean; <(job, nahopjjp= 得知titlfon t> > t/容易 .incrr/> <-align:beansns:bean;

    Joo hu;obicballt><-align:beansns:bean; <-align:beansns:bean;

    h5的/foac&inherit;"t><理域对象<从文件中读取一行 nt>gONED任这些 iv>i <-align:beansns:bean; <-align:beansns:bean;

    h5的/foac&inherit;"t><理域对象<将hopjjp= l-aliSo>o h5的/foac&inherit;"t><理域对象<行ncrpa些 .incrpan>&inherit;"t><理域对象<传递ncrpa些 .incrpan>&inherit;"t><理域对象<到ncrpa些tory;/tl-aliLineTokenizer#tokenize )>o h5的/foac&inherit;"t><理域对象<方法中以检索llt><-align:beansns:bean; oh-from> h5的/foac&inherit;"t><理域对象< .incrpa些ONED任这些 iv>i <-align:beansns:bean; <-align:beansns:bean;

    h5的/foac&inherit;"t><理域对象<将hopjjp= l-aliFieldSe >oh-from> h5的/foac&inherit;"t><理域对象<令牌化 rpa些tory;/tl-aliFieldSe Mapper>o h5的/foac&inherit;"t><理域对象<返回的p果ncrpa些 .incrpan>&inherit;"t><理域对象<传递ncrpa些 .incrpan>&inherit;"t><理域对象<给ncrpa些 .incrpan>&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象<方法hopjjp= .incrpan>&inherit;"t><理域对象<的p果ncrpa些 .incrpan>&inherit;"t><理域对象< nt>gONED任这些 iv>i <-align:beansns:bean; <-align:beansns:bean; ean;<-align:beansns:bean; <(job, > t/rpa些tory;/tl-aliFieldSe >oh-from> h5的/foac&inherit;"t><理域对象<和将a映射ncrpa些tory;/tl-aliFieldSe >oh-from> h5的/foac&inherit;"t><理域对象<到域对象 .incrpa些> > t/rpa些tory;/tl-aliLineTokenizer>o h5的/foac&inherit;"t><理域对象<的输入与t/rpa些tory;/tl-aliLineMapper>o h5的/foac&inherit;"t><理域对象<(a行>nhopjjp= .incrpan>&inherit;"t><理域对象<的输入匹配ncrpa些 .incrpan>&inherit;"t><理域对象 > t/rpa些tory;/tl-aliFieldSe Mapper>o h5的/foac&inherit;"t><理域对象<的输出匹配ncrpa些tory;/tl-aliLineMapper>o h5的/foac&inherit;"t><理域对象<,ncrpa些 .incrpan>&inherit;"t><理域对象<所以提供ncrpa些 .incrpan>&inherit;"t><理域对象<了hopjjp= l-aliLineTokenizer>o h5的/foac&inherit;"t><理域对象<同时 nt>g 使&Som jd予想/latask>o h5的/foac&inherit;"t><理域对象< .incrpa些 .incrpan>&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象<,C下面bCRp定义所bLal-代表bCR行为大多数phe户需要ahopjjp= 得知titlfon t> > t/容易 .incrr/> <-align:beansns:b new a;obLyL <和 iher ro继iher niher bLyL <和 iher ro继obLoaryLts aunch-fromobLnimplema bLyL <和 iher ro继obLoaryLts tid", <易 松ont 立obLnerivae>oaryLLineTokenizer tokenizer; 使 /业Ca 使 /业Ca ns:b 确l-keyworNoyLtid">nerivae>oaryLFieldSe Mapperts Ttid"fieldSe Mapper; 使 /业Ca 使 /业Ca ns:b 确l-keyworNoSuchaullig<和 iher ro继yLtid">new a;obLyL T <和 iher ro继obLode>f R n 使 /业Ca t>nint aryL lineNumber)>oaryL 易 松ont 立yLtid">nthrows aryLExcepaull cher.rullt><-ali 易 松ont 立yLtid">nreturn aryLfieldSe Mapper.mapFieldSe (tokenizer.tokenize line)); 使 /业Ca -ali} 使 /业Ca 使 /业Ca ns:b 确l-keyworNoSuchaullig<和 iher ro继yLtid">new a;obLyL <和 iher ro继yLtid">nvoidbLyL <和 iher ro继obLoaryL R n 使 /业Ca t><-ali 易 松ont 立yLtid">nthis aryL.tokenizer = tokenizer; 使 /业Ca -ali} 使 /业Ca 使 /业Ca ns:b 确l-keyworNoSuchaullig<和 iher ro继yLtid">new a;obLyL <和 iher ro继yLtid">nvoidbLyL <和 iher ro继obLoaryL R n 使 /业Ca t><-ali 易 松ont 立yLtid">nthis aryL.fieldSe Mapper = fieldSe Mapper; 使 /业Ca -ali} 使 /业Ca t> > t/容易 .incrr/> <-align:beansns:bean; <(job, ne而不是内置于阅读器本身中(如在框架的先前版本中所做bCR那样)l-&inphe户在控制解析过程时具有更大bCRp活性l-尤其是C需要访问原始行的情况下 nt>gONED任这些 iv>i 容易 .incrr/> e nt><-align:beansns:bns:b>h5人simpleDelimitedFileReadExample">ne>Joo hunk } : e e>Jo系轻- }n䟺Manaunufont> } gONED任h5allt><-align:beansns:b <-align:beansns:bean; <(job, nphe实际域方案读取平面文件 .incrpa些>&inhe文件中读取足球运动员ahopjjp= 得知titlfon t> > t/容易 .incrr/> <-align:beansns:b ne>置l-出生年份l-首次亮相hopjjp= opjjp= opjj, nenh尼>neWre1945e1967”l-ncrpa些tory;/topjjp= opjj, ne鲍勃>netee1946e1969”l-ncrpa些tory;/topjjp= opjj, > t/容易 .incrr/> <-align:beansns:bean; <(job, > t/rpa些tory;/tl-aliPlayer>o h5的/foac&inherit;"t><理域对象<域对象l-ahopjjp= 得知titlfon t> > t/容易 .incrr/> <-align:beansns:b new a;obLyL <和 iher ro继iher niher bLyL <和 iher ro继obLoyL <和 iher ro继yLtid">nimplema bLyL <和 iher ro继obLnerivae>oaryLSo ID; ns:b 确l-keyworNoyLtid">nerivae>oaryLSo -ktName; ns:b 确l-keyworNoyLtid">nerivae>oaryLSo firktName; ns:b 确l-keyworNoyLtid">nerivae>oaryLSo posull; ns:b 确l-keyworNoyLtid">nerivae>oaryL<易 松ont 立yLtid">nint aryL birthYear; ns:b 确l-keyworNoyLtid">nerivae>oaryL<易 松ont 立yLtid">nint aryL debutYear; 使 /业Ca 使 /业Ca ns:b 确l-keyworNoSuchaullig<和 iher ro继yLtid">new a;obLyL So <和 iher ro继obLoaryL R n 使 /业Ca t><-ali 易 松ont 立yLtid">nreturn aryL易 松ont 立sto">PLAYER:ID=" aryL + ID + 易 松ont 立sto">,L-kt Name=" aryL + -ktName +llt><-align:b易 松ont 立sto">,Firkt Name=" aryL + firktName + 易 松ont 立sto">,Posull=" aryL + posull +llt><-align:b易 松ont 立sto">,Birth Year=" aryL + birthYear + 易 松ont 立sto">,DebutYear=" aryL + 使 /业Ca ns:bbbbbbbbbdebutYear; 使 /业Ca bbbb} 使 /业Ca 使 /业Ca ns:b 确l-keyworNocomma jo// setlars and getlars... aryL t> > t/容易 .incrr/> <-align:beansns:bean; <(job, oh-from> h5的/foac&inherit;"t><理域对象<到一ullt/rpa些tory;/tl-aliPlayer>o h5的/foac&inherit;"t><理域对象<对象l-ncrpa些tory;/tl-aliFieldSe Mapper>o h5的/foac&inherit;"t><理域对象<需要定义 nt>g 使&Som jd予想/latask>ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t> > t/容易 .incrr/> <-align:beansns:b nerotectedbLyL <和 iher ro继yLtid">nstat;obLyL <和 iher ro继iher niher bLyL <和 iher ro继obLoaryL <和 iher ro继yLtid">nimplema bLyL <和 iher ro继obLoaryLts aunch-fromobLoyLtid" cher.ru ns:b 确l-keyworNoSuchaullig<和 iher ro继yLtid">new a;obLyL Player <和 iher ro继obLode>f R n 使 /业Ca t>oaryL cher.rub, nnewbLyL Player(); 使 /业Ca b, 0bLyL)); 使 /业Ca -ali player.setL-ktName(fieldSe .oeadSo(<和 iher ro继number">1bLyL)); 使 /业Ca -ali player.setFirktName(fieldSe .oeadSo(<和 iher ro继number">2bLyL)); 使 /业Ca -ali player.setPosull(fieldSe .oeadSo(<和 iher ro继number">3bLyL)); 使 /业Ca -ali player.setBirthYear(fieldSe .oeadInt(<和 iher ro继number">4bLyL)); 使 /业Ca -ali player.setDebutYear(fieldSe .oeadInt(<和 iher ro继number">5bLyL)); 使 /业Ca 使 /业Ca -ali 易 松ont 立yLtid">nreturn aryLplayer; 使 /业Ca -ali} 使 /业Ca t> > t/容易 .incrr/> <-align:beansns:bean; <(job, oh-from> h5的/foac&inherit;"t><理域对象<并调pheauncher.run(job, > t/rpa些 .incrpan>&inherit;"t><理域对象<来读取文件t/rpa些tory;/tl-alioead>o h5的/foac&inherit;"t><理域对象<>ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t> > t/容易 .incrr/> <-align:beansns:b nnewbLyL FlatFileItemReaderts tid"(); 使 /业Ca itemReader.setResource(<和 iher ro继yLtid">nnewbLyL FileSystemResource(<和 iher ro继sto">resources/players.csv"bLyL)); 确l-keyworNocomma jo//DelimitedLineTokenizer defaults to comma asits delimiter>oyL DefaultLineMapperts Playertid"lineMapper = <和 iher ro继yLtid">nnewbLyL DefaultLineMapperts tid"(); 使 /业Ca lineMapper.setLineTokenizer(<和 iher ro继yLtid">nnewbLyL DelimitedLineTokenizer()); 使 /业Ca lineMapper.setFieldSe Mapper(<和 iher ro继yLtid">nnewbLyL PlayerFieldSe Mapper()); 使 /业Ca itemReader.setLineMapper(lineMapper); 使 /业Ca itemReader.open(<和 iher ro继yLtid">nnewbLyL ExecuaullC laxt()); 使 /业Ca Player player = itemReader.oead );> > t/容易 .incrr/> <-align:beansns:bean; <(job, o h5的/foac&inherit;"t><理域对象<都nnahopjjp= l-aliPlayer>o h5的/foac&inherit;"t><理域对象<从文件CR每一行t/rpa些> > t/rpa些 .incrpan>&inherit;"t><理域对象<对象 .incrpa些>oh-from> h5的/foac&inherit;"t><理域对象<将返回 nt>gONED任这些 iv>i 容易 .incrr/> e nt><-align:beansns:bns:b>h5人mappFieldsByName">ne>Joo hunk } : e e>Jo系轻- }n䟺Manaunufont> } gONED任h5allt><-align:beansns:b <-align:beansns:bean; <(job, > t/rpa些tory;/tl-aliDelimitedLineTokenizer>o h5的/foac&inherit;"t><理域对象<和ncrpa些tory;/tl-aliFixedLengthTokenizer>o h5的/foac&inherit;"t><理域对象<>n这是C功能上类似pCRJDBCt/rpa些tory;/tl-aliResultSe >oh-from> h5的/foac&inherit;"t><理域对象< .incrpa些>o h5的/foac&inherit;"t><理域对象<实现中的ncrpa些 .incrpan>&inherit;"t><理域对象<任>n种中,auncher.run(job, > t/rpa些 .incrpan>&inherit;"t><理域对象<以提高映射功能pCR可读性 .incrpa些>ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t> > t/容易 .incrr/> <-align:beansns:b <-align:beansns:b nnewbLyL So[] {<和 iher ro继sto">ID"bLyL, <易 松ont 立sto">-ktName"bLyL,<易 松ont 立sto">firktName"bLyL,<易 松ont 立sto">posull"bLyL,<易 松ont 立sto">birthYear"bLyL,<易 松ont 立sto">debutYear"bLyL});> > t/容易 .incrr/> <-align:beansns:bean; <(job, o h5的/foac&inherit;"t><理域对象<可以如>nphe此信息l-ahopjjp= 得知titlfon t> > t/容易 .incrr/> <-align:beansns:b new a;obLyL <和 iher ro继iher niher bLyL <和 iher ro继obLoaryL <和 iher ro继yLtid">nimplema bLyL <和 iher ro继obLoaryLts aunch-fromobLoyLtid" cher.ru ns:b 确l-keyworNoSuchaullig<和 iher ro继yLtid">new a;obLyL Player <和 iher ro继obLode>f R n 使 /业Ca t>oaryL cher.rub, nif cher.r(fs == <和 iher ro继yLtid">nnull>oyL){llt><-align: 易 松ont 立yLtid">nreturn aryL易 松ont 立yLtid">nnull>oyL; 使 /业Ca -ali } 使 /业Ca 使 /业Ca ns:b Player player = <和 iher ro继yLtid">nnewbLyL Player(); 使 /业Ca ns:b player.setID(fs.oeadSo(<和 iher ro继sto">ID"bLyL)); 使 /业Ca -ali player.setL-ktName(fs.oeadSo(<和 iher ro继sto">-ktName"bLyL)); 使 /业Ca -ali player.setFirktName(fs.oeadSo(<和 iher ro继sto">firktName"bLyL)); 使 /业Ca -ali player.setPosull(fs.oeadSo(<和 iher ro继sto">posull"bLyL)); 使 /业Ca -ali player.setDebutYear(fs.oeadInt(<和 iher ro继sto">debutYear"bLyL)); 使 /业Ca -ali player.setBirthYear(fs.oeadInt(<和 iher ro继sto">birthYear"bLyL)); 使 /业Ca 使 /业Ca -ali 易 松ont 立yLtid">nreturn aryLplayer; 使 /业Ca -al} 使 /业Ca t> > t/容易 .incrr/> 容易 .incrr/> e nt><-align:beansns:bns:b>h5人beanWrapperFieldSe Mapper">ne>Joo hunk } : e e>Jo系轻- }n䟺Manaunufont> } gONED任h5allt><-align:beansns:b <-align:beansns:bean; <(job, nenh必编写p定t/rpa些tory;/tl-aliFieldSe Mapper>o h5的/foac&inherit;"t><理域对象<同样繁琐写一ullp定t/rpa些tory;/tl-aliRowMapper>o h5的/foac&inherit;"t><理域对象oer.run(job, g>o h5的/foac&inherit;"t><理域对象<>ne通过npheJ Bean规范将字段名称nh对象上的设置器进行匹配来自动映射字段 nt>g .incrpan>&inherit;"t><理域对象<>ne从而使此操作变得更加容易 nt>g .incrpan>&inherit;"t><理域对象< .incrpa些> > t/rpa些tory;/tl-aliBeanWrapperFieldSe Mapper>o h5的/foac&inherit;"t><理域对象<配置看起来像>&inhe代码片段l-ahopjjp= 得知titlfon t> > t/容易 .incrr/> &idisplay: none;jallt><-align:beansns:b ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">fieldSe Mapper">oyL < aunch-fromattr">iher bLyL=<和 iher ro继sto">org.spoft>oyLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">erototypeBeanName"bLyL aunch-fromattr">valuebLyL=<和 iher ro继sto">elayer"bLyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL 使 /业Ca 使 /业Ca <和 iher ro继ta">ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">elayer"bLyL < aunch-fromattr">iher bLyL=<和 iher ro继sto">org.spoft>scopebLyL=<和 iher ro继sto">erototype"bLyL/tid">oyL> > t/容易 .incrr/> <-align:beansns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象 new a;obLyL FieldSe Mapper <和 iher ro继obLoaryL R n 使 /业Ca t>nnewbLyL BeanWrapperFieldSe Mapper(); 使 /业Ca b, player"bLyL); 使 /业Ca b, nreturn aryLfieldSe Mapper; 使 /业Ca t>使 /业Ca 使 /业Ca <和 iher ro继met prototype"bLyL) <和 iher ro继Suchaullig<和 iher ro继yLtid">new a;obLyL Player <和 iher ro继obLoyL R n 使 /业Ca t>nreturn aryL<和 iher ro继yLtid">nnewbLyL Player(); 使 /业Ca t> > t/容易 .incrr/> <-align:beansns:bean; <(job, oh-from> h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象<与Spo容器查找nh属性名称匹配的设置器相同CR方式 rpa些>neehopjjp= .incrpan>&inherit;"t><理域对象<对象 nt>g .incrpan>&inherit;"t><理域对象n由于这nh原因l-需要原型作phe域) nt>gONED任l-aliFieldSe >oh-from> h5的/foac&inherit;"t><理域对象<映射了hopjjp= .incrpan>&inherit;"t><理域对象<中的每个可phe字段 nt>g .incrpan>&inherit;"t><理域对象<>ne并t/rpa些tory;/tl-aliPlayer>o h5的/foac&inherit;"t><理域对象<返回 rpa些 .incrpan>&inherit;"t><理域对象<了生成的ncrpa些 .incrpan>&inherit;"t><理域对象<对象l-不需要任>n码 nt>gONED任这些 iv>i 容易 .incrr/> e nt><-align:beansns:bns:b>h5人fixedLengthFileFormats">ne>Joo hunk } : e e>Jo系轻- }n䟺Manaunufont> } <-align:beansns:b <-align:beansns:bean; <(job, ne仅详细讨论>定界文件 .incrpa些>是l-它们仅代表文件读取图片pCR一半 .incrpa些>l-ahopjjp= 得知titlfon t> > t/容易 .incrr/> <-align:beansns:b > t/容易 .incrr/> <-align:beansns:bean; <(job, ull大字段>ne>实际上代表了4ullnh同CR字段>nahopjjp= 得知titlfon t> > t/容易 .incrr/> <-align:beansns:bean;

      Joo hu;obicballt><-align:beansns:bean; <-align:beansns:bean;

      h5的/foacna所订购商品CR唯>标识符-12个字符长 .incrpa些ONED任这些 iv>i <-align:beansns:bean; <-align:beansns:bean;

      h5的/foac&inherit;"t><理域对象<数量>na所订购商品CR数量-3个字符长 .incrpa些ONED任这些 iv>i <-align:beansns:bean; <-align:beansns:bean;

      h5的/foac&inherit;"t><理域对象<价格:商品价格-5个字符长 .incrpa些ONED任这些 iv>i <-align:beansns:bean; <-align:beansns:bean;

      h5的/foac&inherit;"t><理域对象<客户:订购商品CR客户CRID-9个字符长 .incrpa些ONED任这些 iv>i <-align:beansns:bean; <-align:beansns:bean; ean;<-align:beansns:bean; <(job, gtory;/tl-aliFixedLengthLineTokenizer>o h5的/foac&inherit;"t><理域对象ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t> > t/容易 .incrr/> &idisplay: none;jallt><-align:beansns:b ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">fixedLengthLineTokenizer">oyL < aunch-fromattr">iher bLyL=<和 iher ro继sto">org.spoft>oyLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">names"bLyL aunch-fromattr">valuebLyL=<和 iher ro继sto">ISIN,QuanobLy,Price,Customer"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">columns"bLyL aunch-fromattr">valuebLyL=<和 iher ro继sto">1-12, 13-15, 16-20, 21-29"bLyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL > t/容易 .incrr/> &idisplay: none;jallt><-align:beansns:b

      ooi discussed above, it returns the same tl-aliFieldSe >oh-fro asif a delimiter had been used. This些 iv>i allows the same approaches to be used域 handl its output, such asuns:b the些 iv>i o > t/容易 .incrr/> <-align:beansns:b i <-align:beansns:bean; <-align:beansns:bean; niallt><-align:beansns:bean; <-align:beansns:bean; <-align:beansns:b <-align:beansns:bean; <(job, o h5的/foac&inherit;"t><理域对象&inherit;"t><理域对象<一ullnh门bCR属性编辑eauncher.run(job, > oer.run(job, g>是l-将hopjjp= l-aliApplit;aullC laxt>oer.run(job, g .incrpan>&inherit;"t><理域对象g>置hopjjp= .incrpan>&inherit;"t><理域对象<自动声明此beant/rpa些 .incrpan>&inherit;"t><理域对象< .incrpa些ONED任这些 iv>i <-align:beansns:bean; <-align:beansns:bean; i <-align:beansns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象 new a;obLyL FixedLengthTokenizer <和 iher ro继obLoaryL R n 使 /业Ca t>nnewbLyL FixedLengthTokenizer(); 使 /业Ca b, ISIN"bLyL, <易 松ont 立sto">QuanobLy"bLyL, <易 松ont 立sto">Price"bLyL, <易 松ont 立sto">Customer"bLyL); 使 /业Ca tokenizer.setColumns(<和 iher ro继yLtid">nnewbLyL Rrr/e(<和 iher ro继number">1bLyL-<和 iher ro继number">12bLyL), <和 iher ro继yLtid">nnewbLyL Rrr/e(<和 iher ro继number">13bLyL-<和 iher ro继number">15bLyL), <和 iher ro继yLtid">nnewbLyL Rrr/e(<和 iher ro继number">16bLyL-<和 iher ro继number">20bLyL), <和 iher ro继yLtid">nnewbLyL Rrr/e(<和 iher ro继number">21bLyL-<和 iher ro继number">29bLyL)); 使 /业Ca 使 /业Ca 易 松ont 立yLtid">nreturn aryLtokenizer; 使 /业Ca t> > t/容易 .incrr/> <-align:beansns:bean; <(job, gtory;/tl-aliFixedLengthLineTokenizer>o h5的/foac&inherit;"t><理域对象<住phe与t/rpa些tory;/tl-aliLineTokenizer>o h5的/foac&inherit;"t><理域对象<上面讨论 nt>g .incrpan>&inherit;"t><理域对象g .incrpan>&inherit;"t><理域对象<接口l-所以它返回的结果与t/rpa些tory;/tl-aliFieldSe >oh-from> h5的/foac&inherit;"t><理域对象g .incrpan>&inherit;"t><理域对象g .incrpan>&inherit;"t><理域对象< .incrpa些>ne>如>pheauncher.run(job, > t/rpa些tory;/tl-aliBeanWrapperFieldSe Mapper>o h5的/foac&inherit;"t><理域对象< nt>gONED任这些 iv>i 容易 .incrr/> e nt><-align:beansns:bns:b>h5人jobfixMatchLineMapper">ne>Joo hunk } : e e>Jo系轻- }n䟺Manaunufont> } gONED任h5allt><-align:beansns:b <-align:beansns:bean; <(job, ne为b单起见l-所有文件读取pLa都做出>关键假设>na文件中bCR所有记录都具有相同CR格式 .incrpa些>是l-并非总是如此 .incrpa些>&inhe文件摘录对此进行n说明l-ahopjjp= 得知titlfon t> > t/容易 .incrr/> <-align:beansns:b > t/容易 .incrr/> <-align:beansns:bean; <(job, o h5的/foac&inherit;"t><理域对象<对象 nt>gONED任l-aliLine>oh-from> h5的/foac&inherit;"t><理域对象<尽管“ LINEA”比“ LINEB”具有更多信息l-e>ncrpa些>&inherit;"t><理域对象<对象 nt>gONED任这些 iv>i <-align:beansns:bean; <(job, oh-from> h5的/foac&inherit;"t><理域对象<单独读取每个行l-e>我们必须指定h同auncher.run(job, > t/rpa些tory;/tl-aliLineTokenizer>o h5的/foac&inherit;"t><理域对象<和ncrpa些tory;/tl-aliFieldSe Mapper>o h5的/foac&inherit;"t><理域对象<对象l-&inncrpa些tory;/tl-aliItemWriter>oh-from> h5的/foac&inherit;"t><理域对象<接收正确bCR项目 .incrpa些>o h5的/foac&inherit;"t><理域对象<通过允许的模式来映射使得这nh容易 nt>gtory;/tl-aliLineTokenizer>o h5的/foac&inherit;"t><理域对象<实和图案ncrpa些tory;/tl-aliFieldSe Mapper>o h5的/foac&inherit;"t><理域对象<实进行配置>ne如图中nhe面pCR子l-ahopjjp= 得知titlfon t> > t/容易 .incrr/> &idisplay: none;jallt><-align:beansns:b ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">orderFileLineMapper">oyL < aunch-fromattr">iher bLyL=<和 iher ro继sto">org.spo...PatlarnMatchComposeLineMapper">oyLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">tokenizers">oyLtid">oyL <和 iher ro继ta">ts aunch-fromname">map>oyLtid">oyL <和 iher ro继ta">ts aunch-fromname">a ry aryL aunch-fromattr">keybLyL=<和 iher ro继sto">USER*"bLyL aunch-fromattr">value-refbLyL=<和 iher ro继sto">userTokenizer">oyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">a ry aryL aunch-fromattr">keybLyL=<和 iher ro继sto">LINEA*"bLyL aunch-fromattr">value-refbLyL=<和 iher ro继sto">lineATokenizer">oyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">a ry aryL aunch-fromattr">keybLyL=<和 iher ro继sto">LINEB*"bLyL aunch-fromattr">value-refbLyL=<和 iher ro继sto">lineBTokenizer">oyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">map>oyLtid">oyL <和 iher ro继ta">ts / aunch-fromname">property aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">fieldSe Mappers">oyLtid">oyL <和 iher ro继ta">ts aunch-fromname">map>oyLtid">oyL <和 iher ro继ta">ts aunch-fromname">a ry aryL aunch-fromattr">keybLyL=<和 iher ro继sto">USER*"bLyL aunch-fromattr">value-refbLyL=<和 iher ro继sto">userFieldSe Mapper">oyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">a ry aryL aunch-fromattr">keybLyL=<和 iher ro继sto">LINE*"bLyL aunch-fromattr">value-refbLyL=<和 iher ro继sto">lineFieldSe Mapper">oyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">map>oyLtid">oyL <和 iher ro继ta">ts / aunch-fromname">property aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL > t/容易 .incrr/> <-align:beansns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象 new a;obLyL PatlarnMatchComposeLineMapper <和 iher ro继obLoaryL R n 使 /业Ca t>nnewbLyL PatlarnMatchComposeLineMapper(); 使 /业Ca b, nnewbLyL HashMapts tid"(<和 iher ro继number">3bLyL); 使 /业Ca tokenizers.put(<和 iher ro继sto">USER*"bLyL, userTokenizer()); 使 /业Ca tokenizers.put(<和 iher ro继sto">LINEA*"bLyL, lineATokenizer()); 使 /业Ca tokenizers.put(<和 iher ro继sto">LINEB*"bLyL, lineBTokenizer()); 使 /业Ca 使 /业Ca lineMapper.setTokenizers(tokenizers); 使 /业Ca b, nnewbLyL HashMapts tid"(<和 iher ro继number">2bLyL); 使 /业Ca mappers.put(<和 iher ro继sto">USER*"bLyL, userFieldSe Mapper()); 使 /业Ca mappers.put(<和 iher ro继sto">LINE*"bLyL, lineFieldSe Mapper()); 使 /业Ca 使 /业Ca lineMapper.setFieldSe Mappers(mappers); 使 /业Ca 使 /业Ca 易 松ont 立yLtid">nreturn aryLlineMapper; 使 /业Ca t> > t/容易 .incrr/> <-align:beansns:bean; <(job, o h5的/foac&inherit;"t><理域对象<实l-e>是它们都nphe相同CRncrpa些tory;/tl-aliFieldSe Mapper>o h5的/foac&inherit;"t><理域对象< nt>gONED任这些 iv>i <-align:beansns:bean; <(job, o h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象<允许两ull通配符具有特殊含义:问号(“?”l-匹配>ull字符>n而星号(“*”l-匹配零ull或多ll字符 .incrpa些>nee上述配置中l-所有模式都n星号结尾>ne从而使它们有效地成为行CR前缀 .incrpa些>o h5的/foac&inherit;"t><理域对象<总是匹配最具体的模式可能l-无论e配置CR顺序 .incrpa些>ne如果将“ LINE *”和“ LINEA *”都列为模式>ne则“ LINEA”将与模式“ LINEA *”匹配>n而“ LINEB”将与模式“ LINE *”匹配 .incrpa些>ne单ull星号(“ *”hopjjp= 得知titlfon t> > t/容易 .incrr/> &idisplay: none;jallt><-align:beansns:b ts aunch-fromname">a ry aryL aunch-fromattr">keybLyL=<和 iher ro继sto">*"bLyL aunch-fromattr">value-refbLyL=<和 iher ro继sto">defaultLineTokenizer">oyL/tid">oyL > t/容易 .incrr/> <-align:beansns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象 *"bLyL, defaultLineTokenizer()); 使 /业Ca ... > t/容易 .incrr/> <-align:beansns:bean; <(job, o h5的/foac&inherit;"t><理域对象<可单独b于标记化 nt>gONED任这些 iv>i <-align:beansns:bean; <(job, >处理这种情况l-需要更复杂的策略 .incrpa些>o h5的/foac&inherit;"t><理域对象<样本中ncrpa些>&inherit;"t><理域对象< .incrpa些ONED任这些 iv>i 容易 .incrr/> e nt><-align:beansns:bns:b>h5人excepaullHandlInFlatFiles">ne>Joo hunk } : e e>Jo系轻- }n䟺Manaunufont> } gONED任h5allt><-align:beansns:b <-align:beansns:bean; <(job, l-对行进行标记可能会引发异常 .incrpa些>&i后可以手动或通过其他批处理作业检查这n日志 .incrpa些>neSpo Batch提供了用于处理解析异常CR异常层次结Rl-auncher.run(job, > t/rpa些tory;/tl-aliFlatFileParseExcepaull>o h5的/foac&inherit;"t><理域对象<和ncrpa些tory;/tl-aliFlatFileFormatExcepaull>o h5的/foac&inherit;"t><理域对象< .incrpa些>错误时 nt>gtory;/tl-aliFlatFileParseExcepaull>o h5的/foac&inherit;"t><理域对象gtory;/tl-aliFlatFileItemReader>oh-from> h5的/foac&inherit;"t><理域对象< nt>gONED任l-aliFlatFileFormatExcepaull>o h5的/foac&inherit;"t><理域对象<由o h5的/foac&inherit;"t><理域对象 接口 nt>g .incrpan>&inherit;"t><理域对象&inherit;"t><理域对象gONED任这些 iv>i <-align:beansns:bean; ne>Joo hunk } : e e>Jo系轻- }n䟺Ml-aliIncorrn TokenCountExcepaull <-align:beansns:bean; <(job, o h5的/foac&inherit;"t><理域对象<并t/rpa些tory;/tl-aliFixedLengthLineTokenizer>o h5的/foac&inherit;"t><理域对象<必须指定可phe于创建>ull列名CR能力ncrpa些tory;/tl-aliFieldSe >o h5的/foac&inherit;"t><理域对象< .incrpa些>是l-如果列名CR数量nh对行进行标记时找到bCR列数h匹配>nncrpa些tory;/tl-aliFieldSe >o h5的/foac&inherit;"t><理域对象< .incrr/> 则无法创建>ne并t/rpa些tory;/tl-aliIncorrn TokenCountExcepaull h5的/foac&inherit;"t><理域对象<引发 nt>g .incrpan>&inherit;"t><理域对象&inherit;"t><理域对象<>ne其中包含遇到的牌数和预期CR数>ne如>&inhebLa所bLa .i l-ahopjjp= 得知titlfon t> > <容易 .incrr/> <-align:beansns:b nnewbLyL So[] {<和 iher ro继sto">A"bLyL, <易 松ont 立sto">B"bLyL, <易 松ont 立sto">C"bLyL, <易 松ont 立sto">D"bLyL}); 使 /业Ca 使 /业Ca <和 iher ro继yLtid">n ry aryLu 使 /业Ca tokenizer.tokenize(<和 iher ro继sto">a,b,c"bLyL); 使 /业Ca t>使 /业Ca 和 iher ro继yLtid">ncatch>oyL(Incorrn TokenCountExcepaull e)u 使 /业Ca er herEquals(<和 iher ro继number">4bLyL, e.getExpn edCount()); 使 /业Ca er herEquals(<和 iher ro继number">3bLyL, e.getActualCount()); 使 /业Ca t> > <容易 .incrr/> <容易 .incrr/> <-align:beansns:bean; <(job, 是在文件中仅找到3个牌l-所以t/rpa些tory;/tl-aliIncorrn TokenCountExcepaull h5的/foac&inherit;"t><理域对象<抛a .incrpa些ONED任这些 iv>i t/容易 .incrr/> <-align:beansns:bean; ne>Joo hunk } : e e>Jo系轻- }n䟺Ml-aliIncorrn LineLengthExcepaull <-align:beansns:bean; <(job, ne因为h分隔格式h同l-每一列必须严格遵守其预定义宽度 .incrpa些>ne则将引发异常>ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t> > <容易 .incrr/> <-align:beansns:b nnewbLyL Rrr/e[] { <和 iher ro继yLtid">nnewbLyL Rrr/e(<和 iher ro继number">1bLyL, <易 松ont 立number">5bLyL), lt><-align:beansns:b <和 iher ro继yLtid">nnewbLyL Rrr/e(<和 iher ro继number">6bLyL, <易 松ont 立number">10bLyL), lt><-align:beansns:b <和 iher ro继yLtid">nnewbLyL Rrr/e(<和 iher ro继number">11bLyL, <易 松ont 立number">15bLyL) }); <和 iher ro继yLtid">n ry aryLu 使 /业Ca tokenizer.tokenize(<和 iher ro继sto">12345"bLyL); 使 /业Ca fail(<和 iher ro继sto">Expn ed Incorrn LineLengthExcepaull"bLyL); 使 /业Ca t>使 /业Ca 和 iher ro继yLtid">ncatch>oyL (Incorrn LineLengthExcepaull ex)u 使 /业Ca er herEquals(<和 iher ro继number">15bLyL, ex.getExpn edLength()); 使 /业Ca er herEquals(<和 iher ro继number">5bLyL, ex.getActualLength()); 使 /业Ca t> > <容易 .incrr/> <容易 .incrr/> <-align:beansns:bean; <(job, ne该行CR总长度为15.>是l-在前面pCRpLa中l-传入了长度为5CR行>ne从而t/rpa些tory;/tl-aliIncorrn LineLengthExcepaull h5的/foac&inherit;"t><理域对象<引发了 .incrpa些>ne而不是仅映射第一列l-可以n行CR处理更早地失败l-并且所包含的息比如果尝试读取apCRp2列失败时所包含的息更多ncrpa些tory;/tl-aliFieldSe Mapper>o h5的/foac&inherit;"t><理域对象< nt>g>是l-在某n情况>l-线bCR长度并不总是恒定CR .incrpa些>ne可以通过'stoct'属性关闭行长bCRe证>ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t> > <容易 .incrr/> <-align:beansns:b nnewbLyL Rrr/e[] { <和 iher ro继yLtid">nnewbLyL Rrr/e(<和 iher ro继number">1bLyL, <易 松ont 立number">5bLyL), <和 iher ro继yLtid">nnewbLyL Rrr/e(<和 iher ro继number">6bLyL, <易 松ont 立number">10bLyL) }); 使 /业Ca tokenizer.setStoct(<和 iher ro继yLtid">nfalsebLyL); 使 /业Ca FieldSe tokens = tokenizer.tokenize(<和 iher ro继sto">12345"bLyL); 使 /业Ca er herEquals(<和 iher ro继sto">12345"bLyL, tokens.readSo(<和 iher ro继number">0bLyL)); 使 /业Ca er herEquals(<和 iher ro继sto">"bLyL, tokens.readSo(<和 iher ro继number">1bLyL)); > <容易 .incrr/> <容易 .incrr/> <-align:beansns:bean; <(job, ne只是auncher.run(job, > o h5的/foac&inherit;"t><理域对象<被调phe了 .incrpa些>gONED任l-aliFieldSe >o h5的/foac&inherit;"t><理域对象<现在已正确创建并返回ncrpa些>g>是l-对于其余值>ne它仅包含空标记 .incrpa些ONED任这些 iv>i t/容易 .incrr/> <-align:beansns:bne>Joo hunk } : e e>Jo系轻- }n/a>6.6.3. tl-aliFlatFileItemWriter>oh-from/h4易 .incrr/> e nt><-align:beansns:bean;<(job, &in务方式编写定界或定长格式 .incrpa些ONED任这些 iv>i 容易 .incrr/> e nt><-align:beansns:bns:b>h5人lineAggregator">ne>Joo hunk } : e e>Jo系轻- }n䟺Ml-aliLineAggregator>oh-from/h5allt><-align:beansns:b <-align:beansns:bean; <(job, o h5的/foac&inherit;"t><理域对象<需要>ull接口将一ull项目并将其转换为h样auncher.run(job, > t/rpa些tory;/tl-aliSo>o h5的/foac&inherit;"t><理域对象oh-from> h5的/foac&inherit;"t><理域对象 > t/容易 .incrr/> <-align:beansns:b new a;obLyL <和 iher ro继iher nterfacebLyL <和 iher ro继obL LineAggregator>oyLts aunch-fromobL T aryLtid" cher.ru 使 /业Ca 使 /业Ca <和 iher ro继Suchaullig<和 iher ro继yLtid">new a;obLyL So <和 iher ro继obL aggregatebLyL R n 使 /业Ca t> > t/容易 .incrr/> <-align:beansns:bean; <(job, oh-from> h5的/foac&inherit;"t><理域对象<是bCR逻辑相反o h5的/foac&inherit;"t><理域对象< nt>gONED任l-aliLineTokenizer>o h5的/foac&inherit;"t><理域对象<接受auncher.run(job, > t/rpa些tory;/tl-aliSo>o h5的/foac&inherit;"t><理域对象<并返回at/rpa些tory;/tl-aliFieldSe >o h5的/foac&inherit;"t><理域对象<>ne而oh-from> h5的/foac&inherit;"t><理域对象<接受o h5的/foac&inherit;"t><理域对象<并返回aauncher.run(job, > t/rpa些tory;/tl-aliSo>o h5的/foac&inherit;"t><理域对象< nt>gONED任这些 iv>i <-align:beansns:bean; ne>Joo hunk } : e e>Jo系轻- }n䟺Ml-aliP ihThroughLineAggregator <-align:beansns:bean; <(job, oh-from> h5的/foac&inherit;"t><理域对象<接口CR nt>g .incrpan>&inherit;"t><理域对象<最基本实现 nt>g .incrpan>&inherit;"t><理域对象<是auncher.run(job, > h5的/foac&inherit;"t><理域对象<>ne它假定对象已经是hull字符串或其字符串表pLa形式可以接受编写>ne如>&inhe代码所bLal-ahopjjp= 得知titlfon t> > <容易 .incrr/> <-align:beansns:b new a;obLyL <和 iher ro继iher niher bLyL <和 iher ro继obL P ihThroughLineAggregator nmplema bLyL <和 iher ro继obL LineAggregator>oyLts aunch-fromobL T aryLtid" cher.ru 使 /业Ca 使 /业Ca <和 iher ro继Suchaullig<和 iher ro继yLtid">new a;obLyL So <和 iher ro继obL aggregatebLyL R n 使 /业Ca t>nreturn aryLitem.toSo(); 使 /业Ca } 使 /业Ca t> > <容易 .incrr/> <容易 .incrr/> <-align:beansns:bean; <(job, 是必须具有apCR优点(ncrpa些tory;/tl-aliFlatFileItemWriter>oh-from(job, 如>务和重新启动支持)>ne则 nt>g>述实现非常有hencrpa些 .incrpan>&inherit;"t><理域对象< nt>gONED任这些 iv>i <容易 .incrr/> 容易 .incrr/> e nt><-align:beansns:bns:b>h5人SmplifiedFileWritExample">ne>Joo hunk } : e e>Jo系轻- }n䟺Manaunufont> } gONED任h5allt><-align:beansns:b <-align:beansns:bean; <(job, g> nt>gONED任l-aliLineAggregator>oh-from> h5的/foac&inherit;"t><理域对象<接口及其最基本bCR实现>neauncher.run(job, > t/rpa些tory;/tl-aliP ihThroughLineAggregator h5的/foac&inherit;"t><理域对象 > t/容易 .incrr/> <-align:beansns:bean;

        Joo hu;obicballt><-align:beansns:bean; <(job, h5的/foac&inherit;"t><理域对象<获得auncher.run(job, > o h5的/foac&inherit;"t><理域对象< nt>gONED任这些 iv>i <(job, o h5的/foac&inherit;"t><理域对象<内容将写入配置CR文件 nt>gONED任这些 iv>i <-align:beansns:bean; <(job, oh-from(job, > t/容易 .incrr/> <-align:beansns:b new a;obLyL <和 iher ro继yLtid">nvoidbLyL <和 iher ro继obL writebLyL R n 使 /业Ca t>n hrow bLyL Excepaull cher.ru 使 /业Ca write(lineAggregator.aggregate(item) + LINE_SEPARATOR); 使 /业Ca t> > t/容易 .incrr/> <-align:beansns:bean; <(job, 所bLal-ahopjjp= 得知titlfon t> > t/容易 .incrr/> &idisplay: none;jallt><-align:beansns:b ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">itemWriter" aryL aunch-fromattr">iher bLyL=<和 iher ro继sto">org.spo...FlatFileItemWriter">oyLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">resource"bLyL aunch-fromattr">valuebLyL=<和 iher ro继sto">file:target/test-outputs/output.txt">oyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">lineAggregator">oyLtid">oyL <和 iher ro继ta">ts aunch-fromname">bean aryL aunch-fromattr">iher bLyL=<和 iher ro继sto">org.spo...P ihThroughLineAggregator"bLyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">property aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL > t/容易 .incrr/> <-align:beansns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象 new a;obLyL FlatFileItemWriter <和 iher ro继obL itemWriter>oyL R n 使 /业Ca t>nreturn aryL <和 iher ro继yLtid">nnewbLyL FlatFileItemWriterBuilderts Footid"() 使 /业Ca .name(<和 iher ro继sto">itemWriter" aryL) 使 /业Ca .resource(<和 iher ro继yLtid">nnewbLyL FileSystemResource(<和 iher ro继sto">target/test-outputs/output.txt">oyL)) 使 /业Ca .lineAggregator(<和 iher ro继yLtid">nnewbLyL P ihThroughLineAggregatorts tid"()) 使 /业Ca .build(); 使 /业Ca t> > t/容易 .incrr/> 容易 .incrr/> e nt><-align:beansns:bns:b>h5人FieldExtractor">ne>Joo hunk } : e e>Jo系轻- }n䟺Ml-aliFieldExtractor>oh-from/h5allt><-align:beansns:b <-align:beansns:bean; <(job, g>是l-CR大多数phe户oh-from(job, ne因此必须将其转换为h行 .incrpa些>&inhe内容l-ahopjjp= 得知titlfon t> > t/容易 .incrr/> <-align:beansns:bean;
          Joo hu;obicballt><-align:beansns:bean; <(job, i <(job, o h5的/foac&inherit;"t><理域对象<方法中l-以检索auncher.run(job, > o h5的/foac&inherit;"t><理域对象< .incrpa些ONED任这些 iv>i <(job, o h5的/foac&inherit;"t><理域对象<牌化ncrpa些tory;/tl-aliFieldSe Mapper>o h5的/foac&inherit;"t><理域对象<返回的结果 nt>g>递 nt>g>g>o h5的/foac&inherit;"t><理域对象<方法 nt>g>g>gONED任这些 iv>i <-align:beansns:bean; <(job, <理域对象<文件写入具有相似>相反CR步骤l-ahopjjp= 得知titlfon t> > t/容易 .incrr/> <-align:beansns:bean;
            Joo hu;obicballt><-align:beansns:bean; <(job, gONED任这些 iv>i <(job, gONED任这些 iv>i <(job, i <-align:beansns:bean; <(job, oh-from(job, ne如>&inhe接口定义所bLal-ahopjjp= 得知titlfon t> > t/容易 .incrr/> <-align:beansns:b new a;obLyL <和 iher ro继iher nterfacebLyL <和 iher ro继obL FieldExtractor>oyLts aunch-fromobL T aryLtid" cher.ru 使 /业Ca 使 /业Ca Object[] extract T item); 使 /业Ca 使 /业Ca t> > t/容易 .incrr/> <-align:beansns:bean; <(job, oh-from(job, g .incrpan>&inherit;"t><理域对象<实现 nt>g .incrpan>&inherit;"t><理域对象<应&提供CR对象CR字段中创建>ull数pl-然后可以nphe元素之间bCR定界符或将其作为固定宽度CR行的部分来写a该数p nt>gONED任这些 iv>i <-align:beansns:bean; ne>Joo hunk } : e e>Jo系轻- }n䟺Ml-aliP ihThroughFieldExtractor>oh-from/h6易 .incrr/> <-align:beansns:bean; <(job, nt>g>g>如数pt/rpa些tory;/tl-aliCollecaull>o h5的/foac&inherit;"t><理域对象o h5的/foac&inherit;"t><理域对象< .incrpa些>这n集合类型之>ul“提取”数p非常b单 .incrpa些>此>ne请将集合转换为数p nt>g>neauncher.run(job, > oh-from(job, g>ne则 nt>gtory;/tl-aliP ihThroughFieldExtractor>oh-from(job, 返回>ull仅包含要提取CR项目CR数p nt>gONED任这些 iv>i t/容易 .incrr/> <-align:beansns:bean; ne>Joo hunk } : e e>Jo系轻- }n䟺Ml-aliBeanWrapperFieldExtractor>oh-from/h6易 .incrr/> <-align:beansns:bean; <(job, o h5的/foac&inherit;"t><理域对象<文件读取部分所述>ne通常最好配置如>将域对象转换为对象数pl-而不是自己编写转换 .incrpa些>oh-from> h5的/foac&inherit;"t><理域对象<提供了此功能l-如图>&inhebLal-ahopjjp= 得知titlfon t> > <容易 .incrr/> <-align:beansns:b nnewbLyL BeanWrapperFieldExtractorts tid"(); 使 /业Ca extractor.setNames(<和 iher ro继yLtid">nnewbLyL So[] { <易 松ont 立sto">first">oyL, <易 松ont 立sto">松t">oyL, <易 松ont 立sto">borl"bLyL }); 使 /业Ca 使 /业Ca So first = <和 iher ro继sto">A.rr"bLyL; 使 /业Ca So 松t = <和 iher ro继sto">Tuo"bLyL; 和 iher ro继yLtid">nintbLyL borl = <和 iher ro继number">1912 aryL; 使 /业Ca 使 /业Ca Name l = <和 iher ro继yLtid">nnewbLyL Name(first, 松t, borl); 使 /业Ca Object[] values = extractor.extract l); 使 /业Ca 使 /业Ca ar herEquals(first, values[<和 iher ro继number">0bLyL]); 使 /业Ca er herEquals(松t, values[<和 iher ro继number">1bLyL]); 使 /业Ca er herEquals(borl, values[<和 iher ro继number">2bLyL]); > <容易 .incrr/> <容易 .incrr/> <-align:beansns:bean; <(job, o h5的/foac&inherit;"t><理域对象<需求字段名称映射t/rpa些tory;/tl-aliFieldSe >o h5的/foac&inherit;"t><理域对象<到提供CR对象 nt>g>CR nt>g .incrpan>&inherit;"t><理域对象 nt>g>g> > < nt>g>oh-from> h5的/foac&inherit;"t><理域对象<需求名称映射到he于创建对象数p的getters .incrpa些>gONED任这些 iv>i <容易 .incrr/> 容易 .incrr/> e nt><-align:beansns:bns:b>h5人delimitedFileWritExample">ne>Joo hunk } : e e>Jo系轻- }n䟺Manaunufont> } gONED任h5allt><-align:beansns:b <-align:beansns:bean; <(job, h5的/foac&inherit;"t><理域对象< .incrpa些>面pCRpLa写ahullb单bCR域对象>ne该对象代表客户帐户CR贷方l-ahopjjp= 得知titlfon t> > t/容易 .incrr/> <-align:beansns:b new a;obLyL <和 iher ro继iher niher bLyL <和 iher ro继obL CustomerCredit aryL cher.ru 使 /业Ca 使 /业Ca <和 iher ro继yLtid">nerivatebLyL 和 iher ro继yLtid">nntbLyL id; <和 iher ro继yLtid">nerivatebLyLSo name; <和 iher ro继yLtid">nerivatebLyLBigDecimal credit; 使 /业Ca 使 /业Ca <和 iher ro继comma jo//getters and setters removed f} ihe > t/容易 .incrr/> <-align:beansns:bean; <(job, ne因此t/rpa些tory;/tl-aliFieldExtractor>oh-from(job, > 必须提供接口 nt>g>g .incrpan>&inherit;"t><理域对象<以及要>phebCR分隔符>ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t> > t/容易 .incrr/> &idisplay: none;jallt><-align:beansns:b ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">itemWriter" aryL aunch-fromattr">iher bLyL=<和 iher ro继sto">org.spoframetidk.batch.item.file.FlatFileItemWriter">oyLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">resource"bLyL aunch-fromattr">abLyL=<和 iher ro继sto">outputResource"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">lineAggregator">oyLtid">oyL <和 iher ro继ta">ts aunch-fromname">bean aryL aunch-fromattr">iher bLyL=<和 iher ro继sto">org.spo...DelimitedLineAggregator">oyLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">delimiter" aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">,"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">fieldExtractor">oyLtid">oyL <和 iher ro继ta">ts aunch-fromname">bean aryL aunch-fromattr">iher bLyL=<和 iher ro继sto">org.spo...BeanWrapperFieldExtractor">oyLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">names" aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">name,credit"bLyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">property aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">property aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL > t/容易 .incrr/> <-align:beansns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象 new a;obLyL FlatFileItemWriterts CustomerCredittid" 和 iher ro继obL itemWriter>oyL R n 使 /业Ca t>n hrow bLyL Excepaull cher.ru 使 /业Ca BeanWrapperFieldExtractorts CustomerCredittid"fieldExtractor = <和 iher ro继yLtid">nnewbLyL BeanWrapperFieldExtractorts tid"(); 使 /业Ca fieldExtractor.setNames(<和 iher ro继yLtid">nnewbLyL So[] {<和 iher ro继sto">name">oyL, <易 松ont 立sto">credit"bLyL}); 使 /业Ca fieldExtractor.afterPropertiesSet(); 使 /业Ca 使 /业Ca DelimitedLineAggregatorts CustomerCredittid"lineAggregator = <和 iher ro继yLtid">nnewbLyL DelimitedLineAggregatorts tid"(); 使 /业Ca lineAggregator.setDelimiter(<和 iher ro继sto">,"bLyL); 使 /业Ca lineAggregator.setFieldExtractor(fieldExtractor); 使 /业Ca 使 /业Ca 易 松ont 立yLtid">nreturn aryL<和 iher ro继yLtid">nnewbLyL FlatFileItemWriterBuilderts CustomerCredittid"() 使 /业Ca .name(<和 iher ro继sto">customerCreditWriter" aryL) 使 /业Ca .resource(outputResource) 使 /业Ca .lineAggregator(lineAggregator) 使 /业Ca .build(); 使 /业Ca t> > t/容易 .incrr/> <-align:beansns:bean; <(job, oh-from> h5的/foac&inherit;"t><理域对象<本b前面pCR内容he于将名称和贷方字段t/rpa些tory;/tl-aliCustomerCredit h5的/foac&inherit;"t><理域对象<转换为对象数pl-然后phe每ll字段之间bCR逗号将其写a nt>gONED任这些 iv>i <-align:beansns:bean; <(job, oh-from> h5的/foac&inherit;"t><理域对象<来自动创建t/rpa些tory;/tl-aliBeanWrapperFieldExtractor>oh-from> h5的/foac&inherit;"t><理域对象<和t/rpa些tory;/tl-aliDelimitedLineAggregator h5的/foac&inherit;"t><理域对象 > >ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t> > t/容易 .incrr/> <-align:beansns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象 new a;obLyL FlatFileItemWriterts CustomerCredittid" 和 iher ro继obL itemWriter>oyL R n 使 /业Ca t>n hrow bLyL Excepaull cher.ru 易 松ont 立yLtid">nreturn aryL<和 iher ro继yLtid">nnewbLyL FlatFileItemWriterBuilderts CustomerCredittid"() 使 /业Ca .name(<和 iher ro继sto">customerCreditWriter" aryL) 使 /业Ca .resource(outputResource) 使 /业Ca .delimited() 使 /业Ca .delimiter(<和 iher ro继sto">|" aryL) 使 /业Ca .names(<和 iher ro继yLtid">nnewbLyL So[] {<和 iher ro继sto">name">oyL, <易 松ont 立sto">credit"bLyL}) 使 /业Ca .build(); 使 /业Ca t> > t/容易 .incrr/> 容易 .incrr/> e nt><-align:beansns:bns:b>h5人fixedWidthFileWritExample">ne>Joo hunk } : e e>Jo系轻- }n䟺Manaunufont> } gONED任h5allt><-align:beansns:b <-align:beansns:bean; <(job, h5的/foac&inherit;"t><理域对象< .incrpa些>phe>述相同的t/rpa些tory;/tl-aliCustomerCredit h5的/foac&inherit;"t><理域对象<域对象>ne可以将其配置如>l-ahopjjp= 得知titlfon t> > t/容易 .incrr/> &idisplay: none;jallt><-align:beansns:b ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">itemWriter" aryL aunch-fromattr">iher bLyL=<和 iher ro继sto">org.spoframetidk.batch.item.file.FlatFileItemWriter">oyLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">resource"bLyL aunch-fromattr">abLyL=<和 iher ro继sto">outputResource"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">lineAggregator">oyLtid">oyL <和 iher ro继ta">ts aunch-fromname">bean aryL aunch-fromattr">iher bLyL=<和 iher ro继sto">org.spo...FormatterLineAggregator">oyLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">fieldExtractor">oyLtid">oyL <和 iher ro继ta">ts aunch-fromname">bean aryL aunch-fromattr">iher bLyL=<和 iher ro继sto">org.spo...BeanWrapperFieldExtractor">oyLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">names" aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">name,credit"bLyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">property aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">format" aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">%-9s%-2.0f"bLyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">property aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL <-align:beansns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<-align:beansns:b new a;obLyL FlatFileItemWriterts CustomerCredittid" 和 iher ro继obL itemWriter>oyL R n 使 /业Ca t>n hrow bLyL Excepaull cher.ru 使 /业Ca BeanWrapperFieldExtractorts CustomerCredittid"fieldExtractor = <和 iher ro继yLtid">nnewbLyL BeanWrapperFieldExtractorts tid"(); 使 /业Ca fieldExtractor.setNames(<和 iher ro继yLtid">nnewbLyL So[] {<和 iher ro继sto">name">oyL, <易 松ont 立sto">credit"bLyL}); 使 /业Ca fieldExtractor.afterPropertiesSet(); 使 /业Ca 使 /业Ca FormatterLineAggregatorts CustomerCredittid"lineAggregator = <和 iher ro继yLtid">nnewbLyL FormatterLineAggregatorts tid"(); 使 /业Ca lineAggregator.setFormat(<和 iher ro继sto">%-9s%-2.0f"bLyL); 使 /业Ca lineAggregator.setFieldExtractor(fieldExtractor); 使 /业Ca 使 /业Ca 易 松ont 立yLtid">nreturn aryL<和 iher ro继yLtid">nnewbLyL FlatFileItemWriterBuilderts CustomerCredittid"() 使 /业Ca .name(<和 iher ro继sto">customerCreditWriter" aryL) 使 /业Ca .resource(outputResource) 使 /业Ca .lineAggregator(lineAggregator) 使 /业Ca .build(); 使 /业Ca t> > t/容易 .incrr/> <-align:beansns:b <-align:beansns:bean; <(job, g>是l-format属性pCR值是new>ne并显pLae&inhe元素中l-ahopjjp= 得知titlfon t> > t/容易 .incrr/> &idisplay: none;jallt><-align:beansns:b <-align:beansns:b ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">format" aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">%-9s%-2.0f"bLyL/tid">oyL <-align:beansns:b nnewbLyL FormatterLineAggregatorts tid"(); 使 /业Ca lineAggregator.setFormat(<和 iher ro继sto">%-9s%-2.0f"bLyL); 使 /业Ca ... > t/容易 .incrr/> <-align:beansns:b <-align:beansns:bean; <(job, phe>t/rpa些tory;/tl-aliFormatter h5的/foac&inherit;"t><理域对象g> > t/ nt>g> > t/ nt>gtory;/tl-aliFormatter h5的/foac&inherit;"t><理域对象<基于t/rpa些tory;/tl-alipotf h5的/foac&inherit;"t><理域对象g> > t/ nt>g>g>配置格式化程序pCR大多数详细信息>ne可以et/rpa些tory;/taataerhttps://docs.oracle.com/ se/8/docs/api/ /util/Formattern; n;" iher : e e>Jo系轻- } h5的/foac&inherit;"t><理域对象 } &inherit;"t><理域对象< .incrpa些ONED任这些 iv>i <-align:beansns:bean; <(job, oh-from> h5的/foac&inherit;"t><理域对象<来自动创建t/rpa些tory;/tl-aliBeanWrapperFieldExtractor>oh-from> h5的/foac&inherit;"t><理域对象<和t/rpa些tory;/tl-aliFormatterLineAggregator h5的/foac&inherit;"t><理域对象 > >ne如>&inhebLa所bLal-ahopjjp= 得知titlfon t> > t/容易 .incrr/> <-align:beansns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<-align:beansns:b new a;obLyL FlatFileItemWriterts CustomerCredittid" 和 iher ro继obL itemWriter>oyL R n 使 /业Ca t>n hrow bLyL Excepaull cher.ru 易 松ont 立yLtid">nreturn aryL<和 iher ro继yLtid">nnewbLyL FlatFileItemWriterBuilderts CustomerCredittid"() 使 /业Ca .name(<和 iher ro继sto">customerCreditWriter" aryL) 使 /业Ca .resource(outputResource) 使 /业Ca .formatted() 使 /业Ca .format(<和 iher ro继sto">%-9s%-2.0f"bLyL) 使 /业Ca .names(<和 iher ro继yLtid">nnewbLyL So[] {<和 iher ro继sto">name">oyL, <易 松ont 立sto">credit"bLyL}) 使 /业Ca .build(); 使 /业Ca t> > t/容易 .in, > t/容易 .in, 容易 .incrr/> e nt><-align:beansns:bns:b>h5人handlingFileCreaaulligJoo hunk } : e e>Jo系轻- } } <-align:beansns:b <-align:beansns:bean; o h5的/foac&inherit;"t><理域对象<文件资源有非常b单pCR关系 .incrpa些 ne它将打开文件(如果存e)l-如果没有>ne则引发异常 nt>g>h看>ne似>应该存e类似pCRp单pahopjjp= l-aliFlatFileItemWriter>oh-from(job, g>是l-可能重新启动hopjjp= l-aliJob>oh-from> h5的/foac&inherit;"t><理域对象<可能-a导致问题 .incrpa些>g>是l-如果此作业CR文件名始终相同-a怎样?ncrpa些>g>oh-from(job, > 包含属性t/rpa些tory;/tl-alishouldDeleteIfExjn s h5的/foac&inherit;"t><理域对象< .incrpa些>i Joo hunk } : e e>Jo系轻- } } <-align:beansns:b<(job, gONED任这些 iv>i<-align:beansns:b <-align:beansns:bean; <-align:beansns:b <理域对象< .incrpan>&inherit;"t><理域对象<流XMLCR约束 nt>gONED任容易 ><-align:beansns:b <-align:beansns:bean; <(job, ne因为其他标准XML解析API不能满足批处理要求(DOMh次将整ull输入加载到内存中l-而SAX通过允许phe户&提供回调来控制解析过el- .incrpa些ONED任这些 iv>i <-align:beansns:bean;<-align:beansns:bean;<-align:beansns:b<(job, 工作 .incrpa些>ne但在Spo Batch XML处理中很常见 .incrpa些>o h5的/foac&inherit;"t><理域对象<需要标记t/ nt>g>ne它假aXML资源是各ull记录相对应CR“片段”b集合,如>图所bLal-ahopjjp= 得知titlfon t><-align:beansns:b<-align:beansns:bean;XML输入jallt><-align:beansns:b<容易 				 .incrr/>
  e nt><f<obL			 .incrpan>&inherit;<理域对象< .incrpan>&inherit;"t><理域对象<图17. XML输入 nt>gONED任容易 ><-align:beans<-align:beansns:b<(job, g>是l-Spo Batch不任>特定CRXML绑定技术绑定 .incrpa些><-align:beansns:b< nt>gONED任aataerhttps://docs.spo.io/spo/docs/curra /spo-frametidk-aera ce/gnheraccessn; n;"oxm" iher : e e>Jo系轻- } h5的/foac&inherit;"t><理域对象 } ne它为最流行的OXM技术提供统hCR抽象 nt>g>图显pLa了OXM支持CR技术CR关系l-ahopjjp= 得知titlfon t><-align:beansns:b<-align:beansns:bean;OXM绑定jallt><-align:beansns:b<容易 				 .incrr/>
  e nt><f<obL			 .incrpan>&inherit;<理域对象< .incrpan>&inherit;"t><理域对象<图18. OXM绑定 nt>gONED任容易 ><-align:beans<-align:beansns:b<(job, 住pheXML片段表pLa记录l-我们现在可以更仔细地检查读者和作家 .incrpa些ONED任这些 iv>i<-align:beansns:bJoo hunk } : e e>Jo系轻- }oh-from/h4易 .incrr/> e nt><-align:beansns:bean;<(job, gONED任l-aliStaxEva ItemReader>oh-from(job, gONED任l-aliStaxEva ItemReader>oh-from(job, g>&inheXML记录集t/ nt>g> <容易 .incrr/> e nt><-align:beansns:b oyL <和 iher ro继ta">ts aunch-fromname">record bLyLtid">oyL <和 iher ro继ta">ts aunch-fromname">trade aryL aunch-fromattr">xmln bLyL=<和 iher ro继sto">https://spoframetidk.org/batch/sample/io/oxm/domair"bLyLtid">oyL <和 iher ro继ta">ts aunch-fromname">ins:bLyLtid">oyLXYZ0001<和 iher ro继ta">ts / aunch-fromname">ins:bLyLtid">oyL <和 iher ro继ta">ts aunch-fromname">quantity aryLtid">oyL5<和 iher ro继ta">ts / aunch-fromname">quantity aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">poce aryLtid">oyL11.39<和 iher ro继ta">ts / aunch-fromname">prce aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">customer aryLtid">oyLCustomer1<和 iher ro继ta">ts / aunch-fromname">customer aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">trade aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">trade aryL aunch-fromattr">xmln bLyL=<和 iher ro继sto">https://spoframetidk.org/batch/sample/io/oxm/domair"bLyLtid">oyL <和 iher ro继ta">ts aunch-fromname">ins:bLyLtid">oyLXYZ0002<和 iher ro继ta">ts / aunch-fromname">ins:bLyLtid">oyL <和 iher ro继ta">ts aunch-fromname">quantity aryLtid">oyL2<和 iher ro继ta">ts / aunch-fromname">quantity aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">poce aryLtid">oyL72.99<和 iher ro继ta">ts / aunch-fromname">prce aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">customer aryLtid">oyLCustomer2c<和 iher ro继ta">ts / aunch-fromname">customer aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">trade aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">trade aryL aunch-fromattr">xmln bLyL=<和 iher ro继sto">https://spoframetidk.org/batch/sample/io/oxm/domair"bLyLtid">oyL <和 iher ro继ta">ts aunch-fromname">ins:bLyLtid">oyLXYZ0003<和 iher ro继ta">ts / aunch-fromname">ins:bLyLtid">oyL <和 iher ro继ta">ts aunch-fromname">quantity aryLtid">oyL9<和 iher ro继ta">ts / aunch-fromname">quantity aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">poce aryLtid">oyL99.99<和 iher ro继ta">ts / aunch-fromname">prce aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">customer aryLtid">oyLCustomer3<和 iher ro继ta">ts / aunch-fromname">customer aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">trade aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">record bLyLtid">oyL> t/容易 .in, 容易 .incrr/> e nt><-align:beansns:bean;<(job, &inhe条件ahopjjp= 得知titlfon t> <容易 .incrr/> e nt><-align:beansns:bean; ean;<(job, g>gONED任这些 iv>i ean;<(job, gONED任这些 iv>i ean;oh-from(job, gONED任这些 iv>i 容易 .incrr/> e nt><-align:beansns:bean;<(job, 定义 nt>gONED任l-aliStaxEva ItemReader>oh-from(job, gONED任l-alitrade h-from(job, gONED任l-aliorg/spoframetidk/batch/item/xml/domair/trades.xml>oh-from> h5的/foac&inherit;"t><理域对象<和称为的解组器t/rpa些>phebCR nt>gONED任l-alitradeMarshaller>oh-from(job, gONED任这些 iv>i <容易 .incrr/> e nt>&idisplay: none;jallt><-align:beansns:b ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">itemReaderi aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spoframetidk.batch.item.xml.StaxEva ItemReaderi aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">fragma RootElema Name">oyL aunch-fromattr">valuebLyL=<和 iher ro继sto">trade"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">resource"bLyL aunch-fromattr">valuebLyL=<和 iher ro继sto">org/spoframetidk/batch/item/xml/domair/trades.xml"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">unmarshaller"bLyL aunch-fromattr">abLyL=<和 iher ro继sto">tradeMarshaller"bLyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL 容易 .incrr/> e nt><-align:beansns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<-align:beansns:b new a;obLyL StaxEva ItemReader 和 iher ro继obL itemReader>oyL 和 iher ro继a t>nreturn aryL<和 iher ro继yLtid">nnewbLyL StaxEva ItemReaderBuilderts Tradetid"() 使 /业Ca .name(<和 iher ro继sto">itemReaderi aryL) 使 /业Ca .resource(<和 iher ro继yLtid">nnewbLyL FileSystemResource(<和 iher ro继sto">org/spoframetidk/batch/item/xml/domair/trades.xml"bLyL)) 使 /业Ca .addFragma RootElema s(<和 iher ro继sto">trade"bLyL) 使 /业Ca .unmarshaller(tradeMarshaller()) 使 /业Ca .build(); 使 /业Ca 使 /业Ca t> t/容易 .in, 容易 .incrr/> e nt><-align:beansns:bean;<(job, oh-from(job, gtory;/tl-aliFieldSe >o h5的/foac&inherit;"t><理域对象所bLal-ahopjjp= 得知titlfon t> <容易 .incrr/> e nt>&idisplay: none;jallt><-align:beansns:b ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">tradeMarshaller"bLyL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spoframetidk.oxm.xstream.XStreamMarshalleri aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto"> ases" aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">util:map aryL aunch-fromattr">idbLyL=<和 iher ro继sto"> ases" aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">a ry aryL aunch-fromattr">yLbLyL=<和 iher ro继sto">trade"bLyL .incrr/> aunch-fromattr">valuebLyL=<和 iher ro继sto">org.spoframetidk.batch.sample.domair.trade.Trade"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">a ry aryL aunch-fromattr">yLbLyL=<和 iher ro继sto">prce"bLyL aunch-fromattr">valuebLyL=<和 iher ro继sto"> .math.BigDecimal"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">a ry aryL aunch-fromattr">yLbLyL=<和 iher ro继sto">ins:"bLyL aunch-fromattr">valuebLyL=<和 iher ro继sto"> ..rr/.So"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">a ry aryL aunch-fromattr">yLbLyL=<和 iher ro继sto">customer"bLyL aunch-fromattr">valuebLyL=<和 iher ro继sto"> ..rr/.So"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">a ry aryL aunch-fromattr">yLbLyL=<和 iher ro继sto">quantity"bLyL aunch-fromattr">valuebLyL=<和 iher ro继sto"> ..rr/.Lo"bLyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">util:map aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">property aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL 容易 .incrr/> e nt><-align:beansns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<-align:beansns:b new a;obLyL XStreamMarshaller 和 iher ro继obL tradeMarshaller>oyL 和 iher ro继a t>nnewbLyL HashMapts tid"(); 使 /业Ca ases.put(<和 iher ro继sto">trade"bLyL, Trade.iher ); 使 /业Ca ases.put(<和 iher ro继sto">prce"bLyL, BigDecimal.iher ); 使 /业Ca ases.put(<和 iher ro继sto">ins:"bLyL, So.iher ); 使 /业Ca ases.put(<和 iher ro继sto">customer"bLyL, So.iher ); 使 /业Ca ases.put(<和 iher ro继sto">quantity"bLyL, Lo.iher ); 使 /业Ca 使 /业Ca XStreamMarshallermarshaller = <和 iher ro继yLtid">nnewbLyL XStreamMarshaller(); 使 /业Ca 使 /业Ca marshaller.setA ases( ases); 使 /业Ca 使 /业Ca 易 松ont 立yLtid">nreturn aryLmarshaller; 使 /业Ca t> t/容易 .in, 容易 .incrr/> e nt><-align:beansns:bean;<(job, ne并将该文档传递给解串器(通常是Spo OXM的包装器t/rpa些tory;/teo Unmarshaller>oh-from(job, ne以将XML映射到J 对象 nt>gONED任这些 iv>i <容易 .incrr/> e nt><-align:beansns:bean;<(job, <容易 .incrr/> e nt><-align:beansns:b nnewbLyL StaxEva ItemReaderts tid"(); 使 /业Ca Resource resource = <和 iher ro继yLtid">nnewbLyL ByteArrayResource(xmlResource.getBytes()); 使 /业Ca 使 /业Ca Map ases = <和 iher ro继yLtid">nnewbLyL HashMap(); 使 /业Ca ases.put(<和 iher ro继sto">trade"bLyL,<和 iher ro继sto">org.spoframetidk.batch.sample.domair.trade.Trade"bLyL); 使 /业Ca ases.put(<和 iher ro继sto">prce"bLyL,<和 iher ro继sto"> .math.BigDecimal"bLyL); 使 /业Ca ases.put(<和 iher ro继sto">customer"bLyL,<和 iher ro继sto"> ..rr/.So"bLyL); 使 /业Ca ases.put(<和 iher ro继sto">ins:"bLyL,<和 iher ro继sto"> ..rr/.So"bLyL); 使 /业Ca ases.put(<和 iher ro继sto">quantity"bLyL,<和 iher ro继sto"> ..rr/.Lo"bLyL); 使 /业Ca XStreamMarshallerunmarshaller = <和 iher ro继yLtid">nnewbLyL XStreamMarshaller(); 使 /业Ca unmarshaller.setA ases( ases); 使 /业Ca xmlStaxEva ItemReader.setUnmarshaller(unmarshaller); 使 /业Ca xmlStaxEva ItemReader.setResource(resource); 使 /业Ca xmlStaxEva ItemReader.setFragma RootElema Name(<和 iher ro继sto">trade"bLyL); 使 /业Ca xmlStaxEva ItemReader.open(<和 iher ro继yLtid">nnewbLyL ExecuaullC laxt()); 使 /业Ca 使 /业Ca <和 iher ro继yLtid">nboolean aryLhasNaxt = <和 iher ro继yLtid">ntrue aryL; 使 /业Ca 使 /业Ca Trade trade = <和 iher ro继yLtid">nnull aryL; 使 /业Ca 使 /业Ca <和 iher ro继yLtid">nwhile aryL(hasNaxt) u 使 /业Ca trade = xmlStaxEva ItemReader.read(); 使 /业Ca <和 iher ro继yLtid">nif aryL(trade == <和 iher ro继yLtid">nnull aryL) u 使 /业Ca hasNaxt = <和 iher ro继yLtid">nfalse aryL; 使 /业Ca } 使 /业Ca <和 iher ro继yLtid">nelse aryL u 使 /业Ca System.out.potln(trade); 使 /业Ca } 使 /业Ca t> t/容易 .in, 容易 .incrr/<-align:beansns:bJoo hunk } : e e>Jo系轻- }oh-from/h4易 .incrr/> e nt><-align:beansns:bean;<(job, gONED任l-aliStaxEva ItemWriter>oh-from(job, gONED任l-aliResource>o h5的/foac&inherit;"t><理域对象 h5的/foac&inherit;"t><理域对象< .incrpa些>ne该编R nt>gONED任l-aliResource>o h5的/foac&inherit;"t><理域对象<器住phe自定义事件ncrpa些>gONED任l-aliStartDocuma >oh-from> h5的/foac&inherit;"t><理域对象<和t/rpa些tory;/tl-aliEndDocuma >oh-from> h5的/foac&inherit;"t><理域对象<事件 .incrpa些>&inhebLa住pheauncher.run(job, t/ nt>gONED任l-aliStaxEva ItemWriter>oh-from(job, <容易 .incrr/> e nt>&idisplay: none;jallt><-align:beansns:b ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">itemWriteri aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spoframetidk.batch.item.xml.StaxEva ItemWriteri aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">resource"bLyL aunch-fromattr">abLyL=<和 iher ro继sto">outputResource"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">marshaller"bLyL aunch-fromattr">abLyL=<和 iher ro继sto">tradeMarshaller"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">rootTagName">oyL aunch-fromattr">valuebLyL=<和 iher ro继sto">trade"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">o/tiwriteOutput">oyL aunch-fromattr">valuebLyL=<和 iher ro继sto">true"bLyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL 容易 .incrr/> e nt><-align:beansns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<-align:beansns:b new a;obLyL StaxEva ItemWriter 和 iher ro继obL itemWriter>oyL R n 使 /业Ca t>nreturn aryL<和 iher ro继yLtid">nnewbLyL StaxEva ItemWriterBuilderts Tradetid"() 使 /业Ca .name(<和 iher ro继sto">tradesWriter" aryL) 使 /业Ca .marshaller(tradeMarshaller()) 使 /业Ca .resource(outputResource) 使 /业Ca .rootTagName(<和 iher ro继sto">trade"bLyL) 使 /业Ca .o/tiwriteOutput(<和 iher ro继yLtid">ntrue aryL) 使 /业Ca .build(); 使 /业Ca 使 /业Ca t> t/容易 .in, 容易 .incrr/> e nt><-align:beansns:bean;<(job, <理域对象<前面b配置设置了ull必需p属性>ne并设置了可选auncher.run(job, t/ nt>gONED任l-alio/tiwriteOutput=true h-from> h5的/foac&inherit;"t><理域对象<属性>ne本章前面提到CR用于指a是否可以覆盖现有文件 .incrpa些 .incrpan>&inherit;"t><理域对象<应当注意l->&inhebLa中用于编写b序CR编R器本章前面b阅读bLa中>phebCR编R器完全相同l-ahopjjp= 得知titlfon t> <容易 .incrr/> e nt>&idisplay: none;jallt><-align:beansns:b ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">customerCreditMarshaller"bLyL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spoframetidk.oxm.xstream.XStreamMarshalleri aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto"> ases" aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">util:map aryL aunch-fromattr">idbLyL=<和 iher ro继sto"> ases" aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">a ry aryL aunch-fromattr">yLbLyL=<和 iher ro继sto">customer"bLyL .incrr/> aunch-fromattr">valuebLyL=<和 iher ro继sto">org.spoframetidk.batch.sample.domair.trade.Trade"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">a ry aryL aunch-fromattr">yLbLyL=<和 iher ro继sto">prce"bLyL aunch-fromattr">valuebLyL=<和 iher ro继sto"> .math.BigDecimal"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">a ry aryL aunch-fromattr">yLbLyL=<和 iher ro继sto">ins:"bLyL aunch-fromattr">valuebLyL=<和 iher ro继sto"> ..rr/.So"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">a ry aryL aunch-fromattr">yLbLyL=<和 iher ro继sto">customer"bLyL aunch-fromattr">valuebLyL=<和 iher ro继sto"> ..rr/.So"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">a ry aryL aunch-fromattr">yLbLyL=<和 iher ro继sto">quantity"bLyL aunch-fromattr">valuebLyL=<和 iher ro继sto"> ..rr/.Lo"bLyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">util:map aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">property aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL 容易 .incrr/> e nt><-align:beansns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<-align:beansns:b new a;obLyL XStreamMarshaller 和 iher ro继obL customerCreditMarshaller>oyL R n 使 /业Ca t>nnewbLyL XStreamMarshaller(); 使 /业Ca 使 /业Ca Mapts So, Cher tid" ases = <和 iher ro继yLtid">nnewbLyL HashMapts tid"(); 使 /业Ca ases.put(<和 iher ro继sto">trade"bLyL, Trade.iher ); 使 /业Ca ases.put(<和 iher ro继sto">prce"bLyL, BigDecimal.iher ); 使 /业Ca ases.put(<和 iher ro继sto">ins:"bLyL, So.iher ); 使 /业Ca ases.put(<和 iher ro继sto">customer"bLyL, So.iher ); 使 /业Ca ases.put(<和 iher ro继sto">quantity"bLyL, Lo.iher ); 使 /业Ca 使 /业Ca marshaller.setA ases( ases); 使 /业Ca 使 /业Ca 易 松ont 立yLtid">nreturn aryLmarshaller; 使 /业Ca t> t/容易 .in, 容易 .incrr/> e nt><-align:beansns:bean;<(job, &inhe代码说明了所有讨论的要点>ne展pLa了所需属性bCR编程设置l-ahopjjp= 得知titlfon t> <容易 .incrr/> e nt><-align:beansns:b nnewbLyL FileSystemResource(<和 iher ro继sto">gnhe/outputFile.xml"bLyL) 使 /业Ca 使 /业Ca Map ases = <和 iher ro继yLtid">nnewbLyL HashMap(); 使 /业Ca ases.put(<和 iher ro继sto">trade"bLyL,<和 iher ro继sto">org.spoframetidk.batch.sample.domair.trade.Trade"bLyL); 使 /业Ca ases.put(<和 iher ro继sto">prce"bLyL,<和 iher ro继sto"> .math.BigDecimal"bLyL); 使 /业Ca ases.put(<和 iher ro继sto">customer"bLyL,<和 iher ro继sto"> ..rr/.So"bLyL); 使 /业Ca ases.put(<和 iher ro继sto">ins:"bLyL,<和 iher ro继sto"> ..rr/.So"bLyL); 使 /业Ca ases.put(<和 iher ro继sto">quantity"bLyL,<和 iher ro继sto"> ..rr/.Lo"bLyL); 使 /业Ca Marshallermarshaller = <和 iher ro继yLtid">nnewbLyL XStreamMarshaller(); 使 /业Ca marshaller.setA ases( ases); 使 /业Ca 使 /业Ca StaxEva ItemWriterstaxItemWriter= 使 /业Ca 易 松ont 立yLtid">nnewbLyL StaxEva ItemWriterBuilderts Tradetid"() 使 /业Ca .name(<和 iher ro继sto">tradesWriter" aryL) 使 /业Ca .marshaller(marshaller) 使 /业Ca .resource(resource) 使 /业Ca .rootTagName(<和 iher ro继sto">trade"bLyL) 使 /业Ca .o/tiwriteOutput(<和 iher ro继yLtid">ntrue aryL) 使 /业Ca .build(); 使 /业Ca 使 /业Ca staxItemWriter.afterPropertiesSet(); 使 /业Ca 使 /业Ca ExecuaullC laxt execuaullC laxt = <和 iher ro继yLtid">nnewbLyL ExecuaullC laxt(); 使 /业Ca staxItemWriter.open(execuaullC laxt); 使 /业Ca Trade trade = <和 iher ro继yLtid">nnewbLyL Trade(); 使 /业Ca trade.setPrce(<和 iher ro继number"g11.39XYZ0001"bLyL); 使 /业Ca trade.setQuantity(<和 iher ro继number"g5LbLyL); 使 /业Ca trade.setCustomer(<和 iher ro继sto">Customer1"bLyL); 使 /业Ca staxItemWriter.write(trade); t/容易 .in, 容易 .incrr/<-align:beansJoo hunk } : e e>Jo系轻- } } &inherit;"t><理域对象<-align:beansns:b<(job, &inhe格式CR读取和写入JSON资源的支持l-ahopjjp= 得知titlfon t><-align:beansns:bins:"bLyL: aunch-fromsto">123"bLyL, aunch-fromattr">quantity"bLyL: aunch-fromnumber"g1bLyL, aunch-fromattr">prce"bLyL: aunch-fromnumber"g1.2bLyL, aunch-fromattr">customer"bLyL: aunch-fromsto">foo"bLyL 使 /业Ca }, 使 /业Ca u 使 /业Ca aunch-fromattr">ins:"bLyL: aunch-fromsto">456"bLyL, aunch-fromattr">quantity"bLyL: aunch-fromnumber"g2bLyL, aunch-fromattr">prce"bLyL: aunch-fromnumber"g1.4bLyL, aunch-fromattr">customer"bLyL: aunch-fromsto">bar"bLyL 使 /业Ca } 使 /业Ca ] <-align:beans<-align:beansns:b<(job, &inherit;"t><理域对象i<-align:beansns:bJoo hunk } : e e>Jo系轻- }oh-from/h4易 .incrr/> e nt><-align:beansns:bean;<(job, gONED任l-aliJsllItemReader>oh-from(job, ne并结合中实pauncher.run(job, t/ nt>gONED任l-aliorg.spoframetidk.batch.item. sll.JsllObjn Reader>oh-from(job, phe流API读取大块的JSON对象来实p .incrpa些 .incrpan>&inherit;"t><理域对象<当前提供了>种实pahopjjp= 得知titlfon t> <容易 .incrr/> e nt><-align:beansns:bean; ean;Jo系轻- } } gONED任l-aliorg.spoframetidk.batch.item. sll.JacksllJsllObjn Reader>oh-from这些 iv>i ean;Jo系轻- } } gONED任l-aliorg.spoframetidk.batch.item. sll.GsllJsllObjn Reader>oh-from这些 iv>i 容易 .incrr/> e nt><-align:beansns:bean;<(job, &inhe条件ahopjjp= 得知titlfon t> <容易 .incrr/> e nt><-align:beansns:bean; ean;o h5的/foac&inherit;"t><理域对象&表要读取CRJSON文件 .incrpa些 得知titlfon t> ean;oh-from(job, 容易 .incrr/> e nt><-align:beansns:bean;<(job, 定义hull nt>gONED任l-aliJsllItemReader>oh-from(job, phebCR nt>gONED任l-aliorg/spoframetidk/batch/item/ sll/trades. sll>oh-from> h5的/foac&inherit;"t><理域对象<和auncher.run(job, t/ nt>gONED任l-aliJsllObjn Reader>oh-from(job, <容易 .incrr/> e nt><-align:beansns:b new a;obLyL JsllItemReaderts Tradetid" 和 iher ro继obL jsllItemReader>oyL R n 使 /业Ca t> 易 松ont 立yLtid">nreturn aryL<和 iher ro继yLtid">nnewbLyL JsllItemReaderBuilderts Tradetid"() 使 /业Ca ign:beansns:b . sllObjn Reader(<和 iher ro继yLtid">nnewbLyL JacksllJsllObjn Readerts tid"(Trade.iher )) 使 /业Ca ign:beansns:b .resource(<和 iher ro继yLtid">nnewbLyL Cher PathResource(<和 iher ro继sto">trades. sll"bLyL)) 使 /业Ca ign:beansns:b .name(<和 iher ro继sto">tradeJsllItemReaderi aryL) 使 /业Ca ign:beansns:b .build(); 使 /业Ca t> t/容易 .in, 容易 .incrr/<-align:beansns:bJoo hunk } : e e>Jo系轻- }oh-from/h4易 .incrr/> e nt><-align:beansns:bean;<(job, gONED任l-aliJsllFileItemWriter>oh-fromanaunufont> } t/ nt>gONED任l-aliorg.spoframetidk.batch.item. sll.JsllObjn Marshaller>oh-from(job, gONED任l-aliStobLeo > h5的/foac&inherit;"t><理域对象< .incrpa些>种实pahopjjp= 得知titlfon t> <容易 .incrr/> e nt><-align:beansns:bean; ean;Jo系轻- } } gONED任l-aliorg.spoframetidk.batch.item. sll.JacksllJsllObjn Marshaller>oh-from这些 iv>i ean;Jo系轻- } } gONED任l-aliorg.spoframetidk.batch.item. sll.GsllJsllObjn Marshaller>oh-from这些 iv>i 容易 .incrr/> e nt><-align:beansns:bean;<(job, &inhe条件ahopjjp= 得知titlfon t> <容易 .incrr/> e nt><-align:beansns:bean; ean;o h5的/f o h5的/f &表要写入CRJSON文件bCR nt>g .incrpan>&inherit;"t><理域对象 ean;oh-from(job, 容易 .incrr/> e nt><-align:beansns:bean;<(job, 定义t/ nt>gONED任l-aliJsllFileItemWriter>oh-fromanaunufont> } <容易 .incrr/> e nt><-align:beansns:b new a;obLyL JsllFileItemWriterts Tradetid" 和 iher ro继obL jsllFileItemWriter>oyL R n 使 /业Ca t> 易 松ont 立yLtid">nreturn aryL<和 iher ro继yLtid">nnewbLyL JsllFileItemWriterBuilderts Tradetid"() 使 /业Ca ign:beansns:b . sllObjn Marshaller(<和 iher ro继yLtid">nnewbLyL JacksllJsllObjn Marshallerts tid"()) 使 /业Ca ign:beansns:b .resource(<和 iher ro继yLtid">nnewbLyL Cher PathResource(<和 iher ro继sto">trades. sll"bLyL)) 使 /业Ca ign:beansns:b .name(<和 iher ro继sto">tradeJsllFileItemWriteri aryL) 使 /业Ca ign:beansns:b .build(); 使 /业Ca t> t/容易 .in, 容易 .incrr/<-align:beansJoo hunk } : e e>Jo系轻- } } &inherit;"t><理域对象<多文件输入t/rpa些tory;/t/h3易 .incrr/<-align:beansns:b<(job, gONED任l-aliStepbLeo > h5的/foac&inherit;"t><理域对象< .incrpa些>gONED任l-aliMultiResourceItemReader>oh-from(job, &inhe文件l-ahopjjp= 得知titlfon t><-align:beansns:b<-align:beansns:bns:b<-align:beans<-align:beansns:boh-from> h5的/foac&inherit;"t><理域对象<和t/rpa些tory;/tl-alifile-2.txt>oh-from(job, gONED任l-aliMultiResourceItemReader>oh-from(job, phe通配符l-如图&inhebLal-ahopjjp= 得知titlfon t>&idisplay: none;jallt><-align:beansns:b ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">multiResourceReaderi aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spo...MultiResourceItemReaderi aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">resourcesi aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">iher path:gnhe/input/file-*.txt"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">delegate"bLyL aunch-fromattr">abLyL=<和 iher ro继sto">flatFileItemReaderi aryL /tid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL <-align:beans<-align:beansns:b&inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<-align:beansns:bnew a;obLyL MultiResourceItemReader 和 iher ro继obL multiResourceReader>oyL R n 使 /业Ca t>nreturn aryL<和 iher ro继yLtid">nnewbLyL MultiResourceItemReaderBuilderts Footid"() 使 /业Ca .delegate(flatFileItemReader()) 使 /业Ca .resources(resources()) 使 /业Ca .build(); 使 /业Ca t><-align:beans<-align:beansns:b<(job, gONED任l-aliFlatFileItemReaderbLeo > h5的/foac&inherit;"t><理域对象< .incrpa些>&inherit;"t><理域对象<应该注意bCR是l-h任何其他方法一样 nt>gONED任l-aliItemReaderbLeo > h5的/foac&inherit;"t><理域对象<>ne添加额外CR输入(在这种情况nhe为文件l-可能会在重新启动时引起潜在b问题 .incrpa些 .incrpan>&inherit;"t><理域对象<建议批处理作业>phe其各自CR目录,直到成功完成为止 .incrpa些ONED任这些 iv>i<-align:beansns:b ttbody> ean; h5的/foac&inherit;"t><理域对象< .incrr/> ean;通过>phe输入资源进行排序l- nt>gONED任l-aliMultiResourceItemReader#setCom a;otor(Com a;otor)bLeo > h5的/foac&inherit;"t><理域对象< .incrr/> ean;&i确保在重新启动方案中在业运行之间保留资源排序 .i .incrr/> <-align:beansJoo hunk } : e e>Jo系轻- } } &inherit;"t><理域对象<数据库t/rpa些tory;/t/h3易 .incrr/<-align:beansns:b<(job, ne数据库是批处理bCRh央存储机制 .incrpa些>是l-批处理与其他应pheb序样式不同l-这是由>系统必须>phebCR数据集bCR绝对大小 .incrpa些 .incrpan>&inherit;"t><理域对象<如果一条SQL语句返回100万行l-则结果集可能将所有返回bCR结果保存在内存h,直到读取了所有行 .incrpa些 .incrpan>&inherit;"t><理域对象种类型CR解决方案l-ahopjjp= 得知titlfon t><-align:beansns:b Jo系轻- }gONED任l-aliItemReader>oh-from(job, Jo系轻- }gONED任l-aliItemReader>oh-from(job, <-align:beansns:bJoo hunk } : e e>Jo系轻- } } &inherit;"t><理域对象gONED任l-aliItemReader>oh-from(job, e nt><-align:beansns:bean;<(job, &inherit;"t><理域对象gONED任l-aliResultSet>oh-from(job, gONED任l-aliResultSet>oh-from(job, &inherit;"t><理域对象<调用t/ nt>gONED任l-alinext>oh-from> h5的/foac&inherit;"t><理域对象 t/ nt>gONED任l-aliResultSet>oh-from(job, &inherit;"t><理域对象gONED任l-aliItemReader>oh-from(job, 实p会在初始化时打开游标>ne并在每次调用时将游标向前移动一行 nt>gONED任l-alireadbLeo > h5的/foac&inherit;"t><理域对象<>ne返回hull可he于处理bCR映射对象 .incrpa些ONED任eo close>o h5的/f g .incrpan>&inherit;"t><理域对象<该auncher.run(job, t/ nt>g .incrpan>&inherit;"t><理域对象<方法&i确保释放所有资源 .incrpa些 .incrpan>&inherit;"t><理域对象 t/ nt>gONED任l-aliJdbcTemplate>o h5的/f phe回调模式来完全映射hull对象中的所有行来解决此问题 .incrpa些ONED任eo ResultSet>oh-from(job, 是l-必须分批进行,直到步骤完成 .incrpa些>gONED任l-aliItemReader>oh-from(job, 容易 ><-align:beansns:b<-align:beansns:b 光标bLajallt><-align:beansns:b    <容易 ><-align:beansns:b    <f<和 iherobL			 .incrpan>&inherit;<理域对象< .incrpan>&inherit;"t><理域对象<图19.游标bLahopjjp= 容易 ><-align:beansns:b<容易 .incrr/> e nt><-align:beansns:bean;<(job, t/ nt>gONED任l-aliIDbLeo > h5的/foac&inherit;"t><理域对象<>net/ nt>gONED任l-aliNAME>oh-from> h5的/foac&inherit;"t><理域对象<和t/rpa些tory;/tl-aliBARbLeo > h5的/foac&inherit;"t><理域对象<>ne选择ID大于1小于7的所有行 .i这-将光标b开始(行1)放在ID 2上 .i该行bCR结果应该是ull完全映射bCR nt>gONED任l-aliFoo>oh-from> h5的/foac&inherit;"t><理域对象<对象 .incrpa些ONED任eo read()bLeo > h5的/foac&inherit;"t><理域对象<再次ncrpa些 .incrpan>&inherit;"t><理域对象<调用t/ nt>g>gONED任l-aliFoo>oh-from> h5的/foac&inherit;"t><理域对象g .incrpan>&inherit;"t><理域对象g> t/ nt>gONED任l-alireadbLeo > h5的/foac&inherit;"t><理域对象<>ne从而可以垃圾回收对象(假设没有实变量维护对其b引phe) .incrpa些 得知titlfon t> 容易 ><-align:beansns:b<-align:beansns:bean;Joo hunk } : e e>Jo系轻- }oh-from/h5易 ><-align:beansns:b <-align:beansns:bean; oh-from(job, &inherit;"t><理域对象<它直接与 配合住phe>net/ nt>gONED任l-aliResultSet>oh-from(job, gONED任l-aliDataSource>o h5的/f &inhe数据库架R为l-ahopjjp= 得知titlfon t> 容易 ><-align:beansns:b <-align:beansns:b nCREATE aryL<和 iher ro继yLtid">nTABLE aryLCUSTOMER (llt> 易 松ont 立yLtid">nIDbLaryL<和 iher ro继built_in">BIGINT aryL<和 iher ro继yLtid">nIDENTITY aryLPRIMARY<和 iher ro继yLtid">nKEY aryL,llt> 易 松ont 立yLtid">nNAME>oaryL<和 iher ro继built_in">VARCHARbLaryL(<和 iher ro继number"g45 aryL), 使 /业Ca CREDIT<和 iher ro继built_in">FLOAT aryL ); > 容易 ><-align:beansns:b <容易 ><-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliRowMapper>oh-from(job, g .incrpan>&inherit;"t><理域对象gONED任l-aliCustomerCredit>oh-from> h5的/foac&inherit;"t><理域对象<对象l-ahopjjp= 得知titlfon t> 容易 ><-align:beansns:b <-align:beansns:b new a;obLyL <和 iher ro继iher nnch-fbLyL 和 iher ro继obL CustomerCreditRowMapper>oaryL<和 iher ro继yLtid">nimplema fbLyL 和 iher ro继obL RowMapper>oaryLts aunch-fromobL CustomerCredit aryLtid" cher.ru 使 /业Ca 使 /业Ca <和 iher ro继yLtid">new a;obLyL <和 iher ro继yLtid">nstat;obLyL <和 iher ro继yLtid">nfinalbLyL Sto ID_COLUMN = <和 iher ro继sto">idi aryL; <和 iher ro继yLtid">new a;obLyL <和 iher ro继yLtid">nstat;obLyL <和 iher ro继yLtid">nfinalbLyL Sto NAME_COLUMN = <和 iher ro继sto">name" aryL; <和 iher ro继yLtid">new a;obLyL <和 iher ro继yLtid">nstat;obLyL <和 iher ro继yLtid">nfinalbLyL Sto CREDIT_COLUMN = <和 iher ro继sto">credit" aryL; 使 /业Ca 使 /业Ca <和 iher ro继Suchaullig<和 iher ro继yLtid">new a;obLyL CustomerCredit 和 iher ro继obL mapRow>oyL R n 使 /业Ca t>nint aryL rowNum)bLyL <和 iher ro继yLtid">nthrowfbLyL SQLExcepaull cher.ru 使 /业Ca CustomerCredit customerCredit = <和 iher ro继yLtid">nnewbLyL CustomerCredit(); 使 /业Ca 使 /业Ca customerCredit.setId(rs.getInt(ID_COLUMN)); 使 /业Ca customerCredit.setName(rs.getSto(NAME_COLUMN)); 使 /业Ca customerCredit.setCredit(rs.getBigDecimal(CREDIT_COLUMN)); 使 /业Ca 使 /业Ca 易 松ont 立yLtid">nreturn aryLcustomerCredit; 使 /业Ca } 使 /业Ca t> > 容易 ><-align:beansns:b <容易 ><-align:beansns:b <-align:beansns:bean; h5的/f t/ nt>gONED任l-aliJdbcCursorItemReader>oh-from(job, 关键接口t/ nt>gONED任l-aliJdbcTemplate>o h5的/f o h5的/f gONED任l-aliItemReader>oh-from(job, &inherit;"t><理域对象<就本La而言,假设t/ nt>gONED任l-aliCUSTOMER>oh-from(job, g>g .incrpan>&inherit;"t><理域对象gONED任l-aliJdbcTemplate>o h5的/f 容易 ><-align:beansns:b <-align:beansns:b nnewbLyL JdbcTemplate(gnheSource); 使 /业Ca Ljn customerCredits = jdbcTemplate.query(<和 iher ro继sto">SELECT ID, NAME, CREDITfromCUSTOMER"bLyL, <和 iher ro继yLtid">nnewbLyL CustomerCreditRowMapper()); > 容易 ><-align:beansns:b <容易 ><-align:beansns:b <-align:beansns:bean; h5的/f o h5的/f oh-from> h5的/foac&inherit;"t><理域对象<对象 .incrpa些 .incrpan>&inherit;"t><理域对象<在query方法中>ne从获取连接 .incrr/> o h5的/f oh-from(job, g .incrpan>&inherit;"t><理域对象<该t/ nt>g .incrpan>&inherit;"t><理域对象<方法t/ nt>gONED任l-aliResultSet>oh-from(job, &inherit;"t><理域对象<将此与的方法进行对比 .incrr/> oh-from(job, 容易 ><-align:beansns:b <-align:beansns:b nnewbLyL JdbcCursorItemReader(); 使 /业Ca itemReader.setDataSource(gnheSource); 使 /业Ca itemReader.setSql(<和 iher ro继sto">SELECT ID, NAME, CREDITfromCUSTOMER"bLyL); 使 /业Ca itemReader.setRowMapper(<和 iher ro继yLtid">nnewbLyL CustomerCreditRowMapper()); <和 iher ro继yLtid">nint aryL cou lar = <和 iher ro继number"g0 aryL; 使 /业Ca ExecuaullC laxt execuaullC laxt = <和 iher ro继yLtid">nnewbLyL ExecuaullC laxt(); 使 /业Ca itemReader.open(execuaullC laxt); 使 /业Ca Objn customerCredit = <和 iher ro继yLtid">nnewbLyL Objn (); <和 iher ro继yLtid">nwhilebLyL(customerCredit != <和 iher ro继yLtid">nnullbLyL)u 使 /业Ca customerCredit = itemReader.read(); 使 /业Ca cou lar++; 使 /业Ca t>使 /业Ca itemReader.close(); > 容易 ><-align:beansns:b <容易 ><-align:beansns:b <-align:beansns:bean; h5的/f &inherit;"t><理域对象<如果上面b代码将返回bCR内容ncrpa些ONED任eo customerCredit>oh-from(job, ne则结果将与t/ nt>gONED任l-aliJdbcTemplate>o h5的/f &inherit;"t><理域对象<完全相同 nt>g>g .incrpan>&inherit;"t><理域对象<>是l-CR最大优势 nt>gONED任l-aliItemReader>oh-from(job, gONED任l-alireadbLeo > h5的/foac&inherit;"t><理域对象<方法可以调用一次,可以用写出该项目ncrpa些 l-aliItemWriter>oh-fromanaunufont> } phe获得下一ull项目 .incrr/> h5的/foac&inherit;"t><理域对象< .incrpa些>“块”形式进行项目读取和写入>ne并定期提交l-这是高性能批处理bCR本质 .incrpa些>ne它很容易配置为注入到Spo Batch中hopjjp=ONED任l-aliStepbLeo > h5的/foac&inherit;"t><理域对象 容易 ><-align:beansns:b &idisplay: none;jallt><-align:beansns:bns:b ns:b ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">itemReaderi aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spo...JdbcCursorItemReaderi aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">gnheSource"bLyL aunch-fromattr">abLyL=<和 iher ro继sto">gnheSource"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">sqli aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">seln ID, NAME, CREDITfromCUSTOMER"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">rowMapperi aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">bean aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spoframetidk.batch.sample.domain.CustomerCreditRowMapper"bLyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">property aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL 容易 ><-align:beansns:b <容易 ><-align:beansns:b <-align:beansns:bns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<-align:beansns:bns:b new a;obLyL JdbcCursorItemReaderts CustomerCredittid" 和 iher ro继obL itemReader>oyL R n 使 /业Ca t>nreturn aryL<和 iher ro继yLtid">nnewbLyL JdbcCursorItemReaderBuilderts CustomerCredittid"() 使 /业Ca .gnheSource(<和 iher ro继yLtid">nthifbLyL.gnheSource) 使 /业Ca .name(<和 iher ro继sto">creditReaderi aryL) 使 /业Ca .sql(<和 iher ro继sto">seln ID, NAME, CREDITfromCUSTOMER"bLyL) 使 /业Ca .rowMapper(<和 iher ro继yLtid">nnewbLyL CustomerCreditRowMapper()) 使 /业Ca .build(); 使 /业Ca 使 /业Ca t> > 容易 ><-align:beansns:b <容易 ><-align:beansns:b <-align:beansns:bns:b Joo hunk } : e e>Jo系轻- } } <-align:beansns:bns:b <-align:beansns:bean; h5的/f 在J 中打开游标的方法有很ahopjjp= l-aliJdbcCursorItemReader>oh-from(job, &inherit;"t><理域对象 <容易 ><-align:beansns:bns:b <-align:beansns:bean; &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<表16. JdbcCursorItemReader属性hopjjp=hopjjp=hcapaullallt><-align:beansns:bean; &iwidth: 50%结 &iwidth: 50%结 >oh-lgrou知titlfon t> ttbody>titlfon t> ttr知titlfon t> ttd iheroablb员 h><-left v><-top< p iheroablb员 .incrpan>&inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<忽略警告hopjjp= pM/td知titlfon t> ttd iheroablb员 h><-left v><-top< p iheroablb员 .incrpan>&inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<确定是否记录SQLWarns:bs或导致异常 .incrpa些>o h5的/f tr知titlfon t> ttd iheroablb员 h><-left v><-top< p iheroablb员 .incrpan>&inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象 ttd iheroablb员 h><-left v><-top< p iheroablb员 .incrpan>&inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<当JDBC所>phebCRt/ nt>gONED任l-aliResultSet>oh-from(job, tcrpa些>gONED任l-aliItemReader>oh-from(job, &inherit;"t><理域对象<默认情况nhel-hb出任何提bLa .incrpa些 得M/td知titlfon t> tr知titlfon t> ttd iheroablb员 h><-left v><-top< p iheroablb员 .incrpan>&inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象 ttd iheroablb员 h><-left v><-top< p iheroablb员 .incrpan>&inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<设置基础一次t/ nt>gONED任l-aliResultSet>oh-from(job, g .incrpan>&inherit;"t><理域对象g .incrpan>&inherit;"t><理域对象< .incrpa些 得M/td知titlfon t> tr知titlfon t> ttd iheroablb员 h><-left v><-top< p iheroablb员 .incrpan>&inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象 ttd iheroablb员 h><-left v><-top< p iheroablb员 .incrpan>&inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<设置驱eb序等待hopjjp=ONED任l-aliStatema >oh-from(job, g .incrpan>&inherit;"t><理域对象g>&inherit;"t><理域对象<如果超出限制>net/ nt>gONED任l-aliDataAccessExcepaull>o h5的/f &inherit;"t><理域对象<(有关详细信息l-请咨询您b驱eb序供应商文档) .incrpa些 得M/td知titlfon t> tr知titlfon t> ttd iheroablb员 h><-left v><-top< p iheroablb员 .incrpan>&inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象oopjjp= 得M/td知titlfon t> ttd iheroablb员 h><-left v><-top< p iheroablb员 .incrpan>&inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<由>t/ nt>gONED任l-aliResultSet>oh-from(job, g .incrpan>&inherit;"t><理域对象<相同内容ncrpa些 .incrpan>&inherit;"t><理域对象oh-from(job, gONED任l-aliRowMapper>oh-from(job, gONED任l-aliResultSet.naxt()>oh-from(job, &inherit;"t><理域对象<将此值设置为hopjjp= l-alitrue>o h5的/f gONED任l-aliRowMapper>oh-from(job, g>&inherit;"t><理域对象<之前ncrpa些 .incrpan>&inherit;"t><理域对象<不同l-则引发异常t/ nt>g .incrpan>&inherit;"t><理域对象< .incrpa些 得M/td知titlfon t> tr知titlfon t> ttd iheroablb员 h><-left v><-top< p iheroablb员 .incrpan>&inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<良心>oopjjp= 得M/td知titlfon t> ttd iheroablb员 h><-left v><-top< p iheroablb员 .incrpan>&inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<指bLa是否应将阅读器bCR状态保存在titlfon t> tcrpa些ONED任l-aliExecuaullC laxt>oh-from(job, oh-from(job, tcrpa些ONED任l-alitrue>o h5的/f tr知titlfon t> ttd iheroablb员 h><-left v><-top< p iheroablb员 .incrpan>&inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象 ttd iheroablb员 h><-left v><-top< p iheroablb员 .incrpan>&inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<指bLaJDBC驱eb序是否支持在上设置绝对行t/ nt>gONED任l-aliResultSet>oh-from(job, &inherit;"t><理域对象<建议将其设置为hopjjp= l-alitrue>o h5的/f gONED任l-aliResultSet.absolute()>oh-from(job, o h5的/f tr知titlfon t> ttd iheroablb员 h><-left v><-top< p iheroablb员 .incrpan>&inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象oopjjp= 得M/td知titlfon t> ttd iheroablb员 h><-left v><-top< p iheroablb员 .incrpan>&inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<指bLa用于游标的连接是否应由所有其他处理住phe>ne从而共>同一u务 .incrpa些 .incrpan>&inherit;"t><理域对象<如果将其设置为hopjjp= l-alifalse>o h5的/f phe其自己的连接打开>ne并且不参与其余步骤处理中启动b任何u务 .incrpa些 .incrpan>&inherit;"t><理域对象<如果将此标志设置为>net/ nt>gONED任l-alitrue>o h5的/f netitlfon t> tcrpa些ONED任l-aliExtendedC necaullDataSourceProxy>o h5的/f &inherit;"t><理域对象<当您将此选项设置为hopjjp= l-alitrue>o h5的/f 游标在事务开始期间保持打开状态>ne并在步骤处理中执行提交 .incrpa些>o h5的/f tr知titlfon t> titlfon t> <-align:beansns:b<容易 .incrr/> e nt><-align:beansns:bean;Joo hunk } : e e>Jo系轻- }oh-from/h5易 ><-align:beansns:b <-align:beansns:bean; h5的/f ne这-影响他们是否phe t/ nt>gONED任l-aliJdbcTemplate>o h5的/f o h5的/f oh-from(job, &inherit;"t><理域对象是l-这并不意味着它不能b于批处理 .incrpa些>o h5的/f phebCR所有缓存和脏检查>ne并且可能在批处理方案中引起问题 .incrpa些 .incrpan>&inherit;"t><理域对象<有关无状态和正常休眠会话之间差异bCR更多信息l-请参阅特定休眠版本CR文档 .incrpa些 .incrpan>&inherit;"t><理域对象<在 .incrr/> oh-from(job, o h5的/f gONED任l-aliJdbcCursorItemReader>oh-from(job, hebLa配置住pheJDBC阅读器b同b“客户信phe”bLaahopjjp= 得知titlfon t> 容易 ><-align:beansns:b <-align:beansns:b nnewbLyL HibernateCursorItemReader(); 使 /业Ca itemReader.setQuerySto(<和 iher ro继sto">fromCustomerCredit"bLyL); <和 iher ro继comma jo//For simplicity sake, er ume sessullFactory already obtained.>oyL 使 /业Ca itemReader.setSessullFactory(sessullFactory); 使 /业Ca itemReader.setUseStatelessSessull(<和 iher ro继yLtid">ntruebLyL); <和 iher ro继yLtid">nint aryL cou lar = <和 iher ro继number"g0 aryL; 使 /业Ca ExecuaullC laxt execuaullC laxt = <和 iher ro继yLtid">nnewbLyL ExecuaullC laxt(); 使 /业Ca itemReader.open(execuaullC laxt); 使 /业Ca Objn customerCredit = <和 iher ro继yLtid">nnewbLyL Objn (); <和 iher ro继yLtid">nwhilebLyL(customerCredit != <和 iher ro继yLtid">nnullbLyL)u 使 /业Ca customerCredit = itemReader.read(); 使 /业Ca cou lar++; 使 /nCa t>使 /业Ca itemReader.close(); > 容易 ><-align:beansns:b <容易 ><-align:beansns:b <-align:beansns:bean; h5的/f g .incrpan>&inherit;"t><理域对象<表t/ nt>g>g>gONED任l-aliItemReader>oh-from(job, gONED任l-aliCustomerCredit>oh-from> h5的/foac&inherit;"t><理域对象<对象的方式所述完全相同 nt>g>g .incrpan>&inherit;"t><理域对象<“ useStatelessSessull”属性默认为truel-已在此处添加>ne以引起人们注意打开或关闭该属性的能力 .incrpa些>g .incrpan>&inherit;"t><理域对象<属性hopjjp= .incrpan>&inherit;"t><理域对象<设置基础游标的获取大小auncher.run(job, &inherit;"t><理域对象<,配置非常简单l-如&inhebLa所bLaahopjjp= l-aliJdbcCursorItemReader>oh-from(job, oh-from(job, oh-from(job, 容易 ><-align:beansns:b &idisplay: none;jallt><-align:beansns:bns:b ns:b ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">itemReaderi aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spoframetidk.batch.item.gnhebase.HibernateCursorItemReaderi aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">sessullFactory"bLyL aunch-fromattr">abLyL=<和 iher ro继sto">sessullFactory"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">queryStoi aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">fromCustomerCredit"bLyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL 容易 ><-align:beansns:b <容易 ><-align:beansns:b <-align:beansns:bns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<-align:beansns:bns:b new a;obLyL HibernateCursorItemReader 和 iher ro继obL itemReader>oyL R n 使 /业Ca t>nreturn aryL<和 iher ro继yLtid">nnewbLyL HibernateCursorItemReaderBuilderts CustomerCredittid"() 使 /业Ca .name(<和 iher ro继sto">creditReaderi aryL) 使 /业Ca .sessullFactory(sessullFactory) 使 /业Ca .querySto(<和 iher ro继sto">fromCustomerCredit"bLyL) 使 /业Ca .build(); 使 /业Ca t> > 容易 ><-align:beansns:b <容易 ><-align:beansns:b<容易 .incrr/> e nt><-align:beansns:bean;Joo hunk } : e e>Jo系轻- }oh-from/h5易 ><-align:beansns:b <-align:beansns:bean; h5的/f phe存储过程来获取游标数据 .incrpa些 .incrpan>&inherit;"t><理域对象<其auncher.run(job, oh-from> h5的/foac&inherit;"t><理域对象<工作方式相似t/ nt>gONED任l-aliJdbcCursorItemReader>oh-from(job, ne它不运行查询来获取游标l-而是运行存储过程以返回游标 .incrpa些 .incrpan>&inherit;"t><理域对象<存储过程可以通过三种h同的方式返回游标ahopjjp= 得知titlfon t> 容易 ><-align:beansns:b <-align:beansns:bean; tpM> h5的/f gONED任l-aliResultSet>oh-from(job, n .incrpa些 得知titlfon t> li知titlfon t> tpM> h5的/f n .incrpa些 得知titlfon t> li知titlfon t> tpM> h5的/f <-align:beansns:b <-align:beansns:bean; h5的/f hebLa配置住phe先前bLab同b“客户信phe”bLaahopjjp= 得知titlfon t> 容易 ><-align:beansns:b &idisplay: none;jallt><-align:beansns:bns:b ns:b ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">readeri aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">o.s.batch.item.gnhebase.StoredProcedureItemReaderi aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">gnheSource"bLyL aunch-fromattr">abLyL=<和 iher ro继sto">gnheSource"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">procedureNamei aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">sp_customer_credit"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">rowMapperi aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">bean aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spoframetidk.batch.sample.domain.CustomerCreditRowMapper"bLyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">property aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL 容易 ><-align:beansns:b <容易 ><-align:beansns:b <-align:bea:beansns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<-align:beansns:bns:b > 容易 ><-align:beansns:b <容易 ><-align:beansns:b <-align:beansns:bean; h5的/f 存储过程来提供 t/ nt>gONED任l-aliResultSet>oh-from(job, n .incrpa些 得知titlfon t> <-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-alia-cursor>oh-from(job, n,那么我们需要提供out参数b位置>ne即返回bCRt/ nt>gONED任l-alia-cursor>oh-from(job, hebLa显bLa如何将第hull参数bhea游标ahopjjp= 得知titlfon t> 容易 ><-align:beansns:b &idisplay: none;jallt><-align:beansns:bns:b ns:b ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">readeri aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">o.s.batch.item.gnhebase.StoredProcedureItemReaderi aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">gnheSource"bLyL aunch-fromattr">abLyL=<和 iher ro继sto">gnheSource"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">procedureNamei aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">sp_customer_credit"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">refCursorPosiaulli aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">1"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">rowMapperi aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">bean aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spoframetidk.batch.sample.domain.CustomerCreditRowMapper"bLyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">property aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL 容易 ><-align:beansns:b <容易 ><-align:beansns:b <-align:bea:beansns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<-align:beansns:bns:b new a;obLyL StoredProcedureItemReader 和 iher ro继obL reader>oyL R n 使 /业Ca t>nnewbLyL StoredProcedureItemReader(); 使 /业Ca 使 /业Ca reader.setDataSource(gnheSource); 使 /业Ca reader.setProcedureName(<和 iher ro继sto">sp_customer_credit"bLyL); 使 /业Ca reader.setRowMapper(<和 iher ro继yLtid">nnewbLyL CustomerCreditRowMapper()); 使 /业Ca reader.setRefCursorPosiaull(<和 iher ro继number"g1bLyL); 使 /业Ca 使 /业Ca 易 松ont 立yLtid">nreturn aryLreader; 使 /业Ca t> > 容易 ><-align:beansns:b <容易 ><-align:beansns:b <-align:beansns:bean; h5的/f n返回bCRl-则需要将属性“ hopjjp= 易 松ontmarollig<> h5的/f h5的/f o h5的/f o h5的/f hebLa显bLa了如下内容ahopjjp= 得知titlfon t> 容易 ><-align:beansns:b &idisplay: none;jallt><-align:beansns:bns:b ns:b ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">readeri aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">o.s.batch.item.gnhebase.StoredProcedureItemReaderi aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">gnheSource"bLyL aunch-fromattr">abLyL=<和 iher ro继sto">gnheSource"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">procedureNamei aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">sp_customer_credit"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">Suchaulli aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">true"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">rowMapperi aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">bean aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spoframetidk.batch.sample.domain.CustomerCreditRowMapper"bLyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">property aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL 容易 ><-align:beansns:b <容易 ><-align:beansns:b <-align:bea:beansns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<-align:beansns:bns:b new a;obLyL StoredProcedureItemReader 和 iher ro继obL reader>oyL R n 使 /业Ca t>nnewbLyL StoredProcedureItemReader(); 使 /业Ca 使 /业Ca reader.setDataSource(gnheSource); 使 /业Ca reader.setProcedureName(<和 iher ro继sto">sp_customer_credit"bLyL); 使 /业Ca reader.setRowMapper(<和 iher ro继yLtid">nnewbLyL CustomerCreditRowMapper()); 使 /业Ca reader.setFuchaull(<和 iher ro继yLtid">ntruebLyL); 使 /业Ca 使 /业Ca 易 松ont 立yLtid">nreturn aryLreader; 使 /业Ca t> > 容易 ><-align:beansns:b <容易 ><-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliRowMapper>oh-from(job, oh-from(job, <-align:beansns:b <-align:beansns:bean; h5的/f oh-from(job, &inherit;"t><理域对象<声明和设置它们ne以>hebLa声明了三ull参数 .incrpa些>ne它返回a游标,第ull和第ullin参数则采用type值t/ nt>gONED任l-aliINTEGER>o h5的/f 容易 ><-align:beansns:b &idisplay: none;jallt><-align:beansns:bns:b ns:b ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">readeri aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">o.s.batch.item.gnhebase.StoredProcedureItemReaderi aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">gnheSource"bLyL aunch-fromattr">abLyL=<和 iher ro继sto">gnheSource"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">procedureNamei aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">spo.cursor_Such"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">p t>oyL <和 iher ro继ta">ts aunch-fromname">rjn aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">bean aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spoframetidk.jdbc.core.SqlOutP t>oyL <和 iher ro继ta">ts aunch-fromname">R stouctor-arg aryL aunch-fromattr">ieanbLyL=<和 iher ro继sto">0i aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">newid"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">R stouctor-arg aryL aunch-fromattr">ieanbLyL=<和 iher ro继sto">1i aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">util:R stant aryL aunch-fromattr">staca-fieldbLyL=<和 iher ro继sto">oracle.jdbc.OracleTypes.CURSOR"bLyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">R stouctor-arg aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">bean aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spoframetidk.jdbc.core.SqlP t>oyL <和 iher ro继ta">ts aunch-fromname">R stouctor-arg aryL aunch-fromattr">ieanbLyL=<和 iher ro继sto">0i aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">amou l"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">R stouctor-arg aryL aunch-fromattr">ieanbLyL=<和 iher ro继sto">1i aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">util:R stant aryL aunch-fromattr">staca-fieldbLyL=<和 iher ro继sto"> .sql.Types.INTEGER"bLyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">R stouctor-arg aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">bean aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spoframetidk.jdbc.core.SqlP t>oyL <和 iher ro继ta">ts aunch-fromname">R stouctor-arg aryL aunch-fromattr">ieanbLyL=<和 iher ro继sto">0i aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">custid"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">R stouctor-arg aryL aunch-fromattr">ieanbLyL=<和 iher ro继sto">1i aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">util:R stant aryL aunch-fromattr">staca-fieldbLyL=<和 iher ro继sto"> .sql.Types.INTEGER"bLyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">R stouctor-arg aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">rjn aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">property aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">refCursorPosiaulli aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">1"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">rowMapperi aryL aunch-fromattr">abLyL=<和 iher ro继sto">rowMapperi aryL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">preparedStatema Setteri aryL aunch-fromattr">abLyL=<和 iher ro继sto">p t>oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL 容易 ><-align:beansns:b <容易 ><-align:beansns:b <-align:beansns:bns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<-align:beansns:bns:b new a;obLyL StoredProcedureItemReader 和 iher ro继obL reader>oyL R n 使 /业Ca t>nnewbLyL ArrayLjn ts tid"(); 使 /业Ca p t>nnewbLyL SqlOutP t>newId"bLyL, OracleTypes.CURSOR)); 使 /业Ca p t>nnewbLyL SqlP t>amou l"bLyL, Types.INTEGER); 使 /业Ca p t>nnewbLyL SqlP t>custId"bLyL, Types.INTEGER); 使 /业Ca 使 /业Ca StoredProcedureItemReader reader = <和 iher ro继yLtid">nnewbLyL StoredProcedureItemReader(); 使 /业Ca 使 /业Ca reader.setDataSource(gnheSource); 使 /业Ca reader.setProcedureName(<和 iher ro继sto">spo.cursor_Such"bLyL); 使 /业Ca reader.setP t>nreturn aryLreader; 使 /业Ca t> > 容易 ><-align:beansns:b <容易 ><-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliPreparedStatema Setter>o h5的/f gONED任l-aliJdbcCursorItemReader>oh-from(job, g>g .incrpan>&inherit;"t><理域对象<其他属性中列出bCR所有auncher.run(job, Jo系轻- } h5的/f oh-from> h5的/foac&inherit;"t><理域对象< .incrpa些 得知titlfon t> 容易 ><-align:beansns:b容易 ><-align:beans容易 ><-align:beans nt> Joo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<分页t/ nt>gONED任l-aliItemReader>oh-from> h5的/foac&inherit;"t><理域对象<实施ncrpa些 h4易 .incrr/> e nt><-align:beansns:bean;tpM> h5的/f ne其中每ull查询获取部分结果 .incrpa些 .incrpan>&inherit;"t><理域对象<我们将此部分称为页面 .incrpa些 .incrpan>&inherit;"t><理域对象<每ull查询必须指定起始行号和我们要在页面中返回bCR行数 .incrpa些 得知titlfon t> <容易 .incrr/> e nt><-align:beansns:bean;Joo hunk } : e e>Jo系轻- }oh-from/h5易 ><-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliItemReader>oh-from> h5的/foac&inherit;"t><理域对象<是t/ nt>gONED任l-aliJdbcPags:bItemReader>oh-from> h5的/foac&inherit;"t><理域对象< .incrpa些> oh-from> h5的/foac&inherit;"t><理域对象<需要t/ nt>gONED任l-aliPags:bQueryProvider>oh-from(job, ne因此我们需要t/ nt>gONED任l-aliPags:bQueryProvider>oh-from(job, g>g .incrpan>&inherit;"t><理域对象<还有hull可以 phebCR数据库并确定适当bCRauncher.run(job, oh-from(job, <-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliSqlP gs:bQueryProviderFactoryBean h-from(job, gONED任l-aliseln >oh-from(job, oh-from> h5的/foac&inherit;"t><理域对象<条款 .incrpa些 .incrpan>&inherit;"t><理域对象<您还可以提供hull可选t/ nt>gONED任l-aliw对e>oh-from(job, gONED任l-alisortKey>oh-from(job, <-align:beansns:b <-align:beansns:bean; > > > <理域对象<每ull其他呼叫ncrpa些>g .incrpan>&inherit;"t><理域对象<每ull呼叫传回hull项目hopjjp= l-aliItemReader>oh-from> h5的/foac&inherit;"t><理域对象< .incrpa些> <-align:beansns:b <-align:beansns:bean; h5的/f hebLa配置住phehopjjp= l-aliItemReaders>oh-from(job, g .incrpan>&inherit;"t><理域对象<显bLa的基于游标类似b“客户信phe”bLat/ nt>g .incrpan>&inherit;"t><理域对象 容易 ><-align:beansns:b &idisplay: none;jallt><-align:beansns:bns:b ns:b ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">itemReaderi aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spo...JdbcPags:bItemReaderi aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">gnheSource"bLyL aunch-fromattr">abLyL=<和 iher ro继sto">gnheSource"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">queryProvideri aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">bean aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spo...SqlP gs:bQueryProviderFactoryBeani aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">seln Clausei aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">seln id, name, credit"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">fromClausei aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">fromcustomer"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">w对eClausei aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">w对e stacus=:stacus"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">sortKeyi aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">id"bLyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">property aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">p t>oyL <和 iher ro继ta">ts aunch-fromname">map aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">a ry aryL aunch-fromattr">keybLyL=<和 iher ro继sto">stacus"bLyL aunch-fromattr">valuebLyL=<和 iher ro继sto">NEW"bLyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">map aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">property aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">p geSizei aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">1000"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">rowMapperi aryL aunch-fromattr">abLyL=<和 iher ro继sto">customerMapperi aryL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL 容易 ><-align:beansns:b <容易 ><-align:beansns:b <-align:beansns:bns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<-align:beansns:bns:b new a;obLyL JdbcPags:bItemReader 和 iher ro继obL itemReader>oyL 和 iher ro继a t>nnewbLyL HashMapts tid"(); 使 /业Ca p t>stacus"bLyL, <和 iher ro继sto">NEW"bLyL); 使 /业Ca 使 /业Ca <和 iher ro继yLtid">nreturn aryL<和 iher ro继yLtid">nnewbLyL JdbcPags:bItemReaderBuilderts CustomerCredittid"() 使 /业Ca s:bns:b .name(<和 iher ro继sto">creditReaderi aryL) 使 /业Ca s:bns:b .dataSource(gnheSource) 使 /业Ca s:bns:b .queryProvider(queryProvider) 使 /业Ca s:bns:b .p t>new a;obLyL SqlP gs:bQueryProviderFactoryBean 和 iher ro继obL queryProvider>oyL 和 iher ro继a t>nnewbLyL SqlP gs:bQueryProviderFactoryBean(); 使 /业Ca 使 /业Ca provider.setSeln Clause(<和 iher ro继sto">seln id, name, credit"bLyL); 使 /业Ca provider.setFromClause(<和 iher ro继sto">fromcustomer"bLyL); 使 /业Ca provider.setW对eClause(<和 iher ro继sto">w对e stacus=:stacus"bLyL); 使 /业Ca provider.setSortKey(<和 iher ro继sto">id"bLyL); 使 /业Ca 使 /业Ca <和 iher ro继yLtid">nreturn aryLprovider; 使 /业Ca t> > 容易 ><-align:beansns:b <容易 ><-align:beansns:b <-align:beansns:bean; h5的/f oh-from> h5的/foac&inherit;"t><理域对象<返回bCRt/ nt>gONED任l-aliCustomerCredit>oh-from(job, gONED任l-aliRowMapper>oh-from(job, <容易 ><-align:beansns:b <-align:beansns:bean; h5的/f g .incrpan>&inherit;"t><理域对象<指定ncrpa些>gONED任l-aliw对e>oh-from(job, &inherit;"t><理域对象<每ull条目的键应与命名参数的名称匹配 .incrpa些>ne从1开始 .incrpa些 得知titlfon t> 容易 ><-align:beansns:b容易 ><-align:beans <-align:beansns:bean;Joo hunk } : e e>Jo系轻- }oh-from/h5易 ><-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliItemReader>oh-from> h5的/foac&inherit;"t><理域对象<是t/ nt>gONED任l-aliJpaPags:bItemReader>oh-from> h5的/foac&inherit;"t><理域对象< .incrpa些>gONED任l-aliStatelessSessull h-from> h5的/foac&inherit;"t><理域对象<>ne因此我们必须住pheJPA规范提供b其他功能 .incrpa些>ne因此在>pheJPA进行批处理时l-这是自然的选择 .incrpa些>ne实体分离>ne并清除持久性上下文>ne以允许在处理页面后对实体进行垃圾回收 .incrpa些 得知titlfon t> <容易 ><-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliJpaPags:bItemReader>oh-from> h5的/foac&inherit;"t><理域对象<让你声明hullJPQL语句>ne并递hullauncher.run(job, oh-from> h5的/foac&inherit;"t><理域对象< .incrpa些>ne它每次调用都传回h项内容e以>h其他任何方法相同的基本方式进行读取hopjjp= l-aliItemReader>oh-from> h5的/foac&inherit;"t><理域对象< .incrpa些>hebLa配置住phe前面显bLa的JDBC阅读器相同的“客户信phe”bLaahopjjp= 得知titlfon t> 容易 ><-align:beansns:b &idisplay: none;jallt><-align:beansns:bns:b ns:b ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">itemReaderi aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spo...JpaPags:bItemReaderi aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">entityMan gerFactoryi aryL aunch-fromattr">abLyL=<和 iher ro继sto">entityMan gerFactoryi aryL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">queryStoi aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">seln c fromCustomerCredit h"bLyL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">p geSizei aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">1000"bLyL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL 容易 ><-align:beansns:b <容易 ><-align:beansns:b <-align:beansns:bns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<-align:beansns:bns:b new a;obLyL JpaPags:bItemReader 和 iher ro继obL itemReader>oyL 和 iher ro继a t>nreturn aryL<和 iher ro继yLtid">nnewbLyL JpaPags:bItemReaderBuilderts CustomerCredittid"() 使 /业Ca s:bns:b .name(<和 iher ro继sto">creditReaderi aryL) 使 /业Ca s:bns:b .entityMan gerFactory(entityMan gerFactory()) 使 /业Ca s:bns:b .querySto(<和 iher ro继sto">seln c fromCustomerCredit h"bLyL) 使 /业Ca s:bns:b .p geSize(<和 iher ro继number"g1000 aryL) 使 /业Ca s:bns:b .build(); 使 /业Ca } > 容易 ><-align:beansns:b <容易 ><-align:beansns:b <-align:beansns:bean; h5的/f g .incrpan>&inherit;"t><理域对象<,则ncrpa些 .incrpan>&inherit;"t><理域对象<此配置hopjjp=>h上述完全相同的方式hopjjp= l-aliItemReader>oh-from> h5的/foac&inherit;"t><理域对象<返回t/ nt>gONED任l-aliCustomerCredit>oh-from(job, g .incrpan>&inherit;"t><理域对象< .incrpa些>oh-from> h5的/foacoh-from(job, 容易 ><-align:beansns:b容易 ><-align:beans容易 ><-align:beans nt> Joo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<数据库ItemWljershopjjp= h4易 .incrr/> e nt><-align:beansns:bean;tpM> h5的/f gONED任l-aliItemWljer>oh-from(job, nt>gONED任l-aliItemWljer>oh-from(job, ne因为它们必须表p得像是事务性的>ne跟踪书面项目并在适当bCR时候进行刷新或清除 .incrpa些 .incrpan>&inherit;"t><理域对象<数据库不需要此功能>ne因为写入已包含在>务中 .incrpa些>ne以实p该oh-from(job, ne也可以住phe自定义中的个t/ nt>gONED任l-aliItemWljer>oh-from(job, &inherit;"t><理域对象<无论哪种方式>ne它们都应该正常工作 .incrpa些 .incrpan>&inherit;"t><理域对象<要注意的件>是批处理输出所提供b性能和错误处理功能 .incrpa些>phe休眠方式时最常见l-t/ nt>gONED任l-aliItemWljer>oh-from(job, pheJDBC批处理模式时可能会有相同的问题 .incrpa些>ne因为无法知道是哪hull单独的项目导致了异常,甚至没有任何hull单独的项目负责>ne如下图所示ahopjjp= 得知titlfon t><-align:beans <-align:beansns:bean;tf<和 iherR la joblt><-align:beansns:bean;ean;timg srcerimg/errorOnFlush.p" alt="冲洗错误ballt><-align:beansns:bean;t容易 ><-align:beansns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<图20.冲洗错误hopjjp= 容易 ><-align:beansns:b容易 ><-align:beans <-align:beansns:bean;tpM> h5的/f ne而第15ull项目则抛出a nt>gONED任l-aliDataI lag h5的/foac&inherit;"t><理域对象< .incrpa些><-align:beansns:bean;ean;而言l-所有20ull项目都成功写入>ne因为没有办法知道,直到他们实际上写的是发生错误 .incrpa些ONED任l-aliSessull#flush ) h-from(job, &inherit;"t><理域对象<>ne将清空缓冲区并命中异常 .incrpa些 .incrpan>&inherit;"t><理域对象<此时l-没有任何<-align:beansns:bean;ean;可以做 .incrpa些>务必须回滚 .incrpa些>n,然后会再次写入 .incrpa些>ne如下图所示ahopjjp= 得知titlfon t><-align:beans <-align:beansns:bean;tf<和 iherR la joblt><-align:beansns:bean;ean;timg srcerimg/errorOnWlje.p" alt="写入时出错ballt><-align:beansns:bean;t容易 ><-align:beansns:b &inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<图21.写时出错hopjjp= 容易 ><-align:beansns:b容易 ><-align:beans <-align:beansns:bean;tpM> h5的/f pheHibernate时l-实p的b单准则ncrpa些ONED任l-aliItemWljer>oh-from(job, gONED任l-aliwlje ) h-from(job, ne而Spo Batch在内部将处理ncrpa些ONED任l-aliItemWljer>oh-from(job, &inherit;"t><理域对象<对调用的粒度t/ nt>g .incrpan>&inherit;"t><理域对象< .incrpa些 得知titlfon t><-align:beans容易 ><-align:b容易 ><-align:b nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<重用现有服务hopjjp= h3易 ><-align:beans nt><-align:beansns:b h5的/f h其他应用程序样式结合>phe .incrpa些 .incrpan>&inherit;"t><理域对象<最常见的是在线系统,但它也可以通过移动每种应用程序样式>phebCR必要批量数据来支持集成甚至胖客户端应用程序 .incrpa些>ne许多用户通常都想在其批处理作中重用现有bCRDAO或其他服务 .incrpa些>neSpo容器本身>此操作相当容易 .incrpa些>gONED任l-aliItemReader>oh-from> h5的/foac&inherit;"t><理域对象<或hopjjp= l-aliItemWljer>oh-from(job, ne以满足另ullSpo Batch类的赖关系l-或者因为它确实是h要的t/ nt>gONED任l-aliItemReader>oh-from> h5的/foac&inherit;"t><理域对象<步 .incrpa些>ne但是由于这是hull普遍的问题>neSpo Batch提供实patitlfon t>gONED任l-aliItemReaderAdapjer>oh-from(job, gONED任l-aliItemWljerAdapjer>oh-from(job, ne并设置起来非常b单 .incrpa些>hebLa>phe nt>gONED任l-aliItemReaderAdapjer>oh-from(job, <-align:beans nt>&idisplay: none;jallt><-align:beansns:b ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">itemReaderi aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spoft>oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">targetObjn i aryL aunch-fromattr">abLyL=<和 iher ro继sto">fooServicei aryL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">targetMethodi aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">generaaeFooi aryL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL opjjp= 使 /业Ca <和 iher ro继ta">ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">fooServicei aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spoft>oyL <-align:beans容易 ><-align:beans nt><-align:beansns:b&inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<-align:beansns:bnew a;obLyL ItemReaderAdapjer 和 iher ro继obL itemReader>oyL 和 iher ro继a t>nnewbLyL ItemReaderAdapjer(); 使 /业Ca 使 /业Ca reader.setTargetObjn (fooService()); 使 /业Ca reader.setTargetMethod(<和 iher ro继sto">generaaeFooi aryL); 使 /业Ca 使 /业Ca <和 iher ro继yLtid">nreturn aryLreader; 使 /业Ca } 使 /业Ca 使 /业Ca <和 iher ro继met new a;obLyL FooService 和 iher ro继obL fooService>oyL 和 iher ro继a t>nreturn aryL<和 iher ro继yLtid">nnewbLyL FooService(); 使 /业Ca } <-align:beans容易 ><-align:beans nt><-align:beansns:b h5的/f gONED任l-alitargetMethod>oh-from(job, h以>he合同的合同相同t/ nt>gONED任l-aliread>oh-from(job, gONED任l-alinull>oh-from(job, gONED任l-aliObjn >oh-from(job, ne其他任何因素都会阻止框架知道处理应何时结束l-从而导致无限循环或错误失败oh-from(job, hebLa>phe nt>gONED任l-aliItemWljerAdapjer>oh-from(job, <-align:beans nt>&idisplay: none;jallt><-align:beansns:b ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">itemWljeri aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spoft>oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">targetObjn i aryL aunch-fromattr">abLyL=<和 iher ro继sto">fooServicei aryL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">targetMethodi aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">processFooi aryL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL opjjp= 使 /业Ca <和 iher ro继ta">ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">fooServicei aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spoft>oyL <-align:beans容易 ><-align:beans nt><-align:beansns:b&inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<-align:beansns:bnew a;obLyL ItemWljerAdapjer 和 iher ro继obL itemWljer>oyL 和 iher ro继a t>nnewbLyL ItemWljerAdapjer(); 使 /业Ca 使 /业Ca wljer.setTargetObjn (fooService()); 使 /业Ca wljer.setTargetMethod(<和 iher ro继sto">processFooi aryL); 使 /业Ca 使 /业Ca <和 iher ro继yLtid">nreturn aryLwljer; 使 /业Ca } 使 /业Ca 使 /业Ca <和 iher ro继met new a;obLyL FooService 和 iher ro继obL fooService>oyL 和 iher ro继a t>nreturn aryL<和 iher ro继yLtid">nnewbLyL FooService(); 使 /业Ca } <-align:beans容易 ><-align:b容易 ><-align:b nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<验证输入<-align:beans nt><-align:beansns:b h5的/f &inherit;"t><理域对象<该titlfon t>gONED任l-aliFixedLengthTokenizer>oh-from(job, &inherit;"t><理域对象<类似地>ne尝试以oh-from(job, oh-from(job, g .incrpan>&inherit;"t><理域对象<的索引访问索引ncrpa些>&inherit;"t><理域对象<所有这些类型的异常都被抛出t/ nt>gONED任l-aliread>oh-from(job, ne因为它存在并是hull数字>ne但是会引起异常 .incrpa些 .incrpan>&inherit;"t><理域对象<由于已经有很多验证框架>ne因此Spo Batch会尝试提供其他验证框架 .incrpa些 .incrpan>&inherit;"t><理域对象<相反>ne它提供hull称为的b单接口>net/ nt>gONED任l-aliValignhor>oh-from(job, ne如以>he接口定义所示ahopjjp= 得知titlfon t><-align:beans nt><-align:beansns:bnew a;obLyL <和 iher ro继iher ni larface>oyL 和 iher ro继obL Valignhor>oaryLts aunch-fromobL T aryLtid" cher.ru 使 /业Ca 使 /业Ca ns:b<和 iher ro继Suchaullig<和 iher ro继yLtid">nvoidbLyL 和 iher ro继obL valignhe>oyL 和 iher ro继a t>nthrowfbLyL ValignhullExceptull yL; 使 /业Ca 使 /业Ca } <-align:beans容易 ><-align:beans nt><-align:beansns:b h5的/f gONED任l-alivalignhe>oh-from(job, &inherit;"t><理域对象<该&inherit;"t><理域对象<方法引发异常l-如果有效l-则正常返回 .incrpa些>gONED任l-aliValignhu:bItemProcessor>oh-from(job, ne如以>hebean定义所示ahopjjp= 得知titlfon t><-align:beans nt>&idisplay: none;jallt><-align:beansns:b ts aunch-fromname">bean aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spoft>oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">valignhori aryL aunch-fromattr">abLyL=<和 iher ro继sto">valignhori aryL/tid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL opjjp= 使 /业Ca <和 iher ro继ta">ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">valignhori aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spoft>oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">valignhori aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">bean aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spoft>oyL <和 iher ro继ta">ts / aunch-fromname">property aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL <-align:beans容易 ><-align:beans nt><-align:beansns:b&inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<-align:beansns:bnew a;obLyL Valignhu:bItemProcessor 和 iher ro继obL itemProcessor>oyL 和 iher ro继a t>nnewbLyL Valignhu:bItemProcessor(); 使 /业Ca 使 /业Ca processor.setValignhor(valignhor()); 使 /业Ca 使 /业Ca <和 iher ro继yLtid">nreturn aryLprocessor; 使 /业Ca } 使 /业Ca 使 /业Ca <和 iher ro继met new a;obLyL SpoValignhor 和 iher ro继obL valignhor>oyL 和 iher ro继a t>nnewbLyL SpoValignhor(); 使 /业Ca 使 /业Ca valignhor.setValignhor(<和 iher ro继yLtid">nnewbLyL TradeValignhor()); 使 /业Ca 使 /业Ca <和 iher ro继yLtid">nreturn aryLvalignhor; 使 /业Ca } <-align:beans容易 ><-align:beans nt><-align:beansns:b h5的/f gONED任l-aliBeanValignhu:bItemProcessor>oh-from(job, heb型 nt>gONED任l-aliPersll h-from> h5的/foac&inherit;"t><理域对象<>nahopjjp= 得知titlfon t><-align:beans nt><-align:beansns:bnnch-fbLyL 和 iher ro继obL Persll aryL cher.ru 使 /业Ca 使 /业Ca ns:b<和 iher ro继met nerivnhe>oyL Sto name; 使 /业Ca 使 /业Ca ns:b<和 iher ro继Suchaullig<和 iher ro继yLtid">new a;obLyL 和 iher ro继obL Persll aryL 和 iher ro继a t>nthifbLyL.name = name; 使 /业Ca ns:b} 使 /业Ca 使 /业Ca ns:b<和 iher ro继Suchaullig<和 iher ro继yLtid">new a;obLyL Sto 和 iher ro继obL getNamebLyL 和 iher ro继a t>nreturn aryLname; 使 /业Ca ns:b} 使 /业Ca 使 /业Ca ns:b<和 iher ro继Suchaullig<和 iher ro继yLtid">new a;obLyL <和 iher ro继yLtid">nvoidbLyL 和 iher ro继obL setNamebLyL 和 iher ro继a t>nthifbLyL.name = name; 使 /业Ca ns:b} 使 /业Ca 使 /业Ca } <-align:beans容易 ><-align:beans nt><-align:beansns:b h5的/f gONED任l-aliBeanValignhu:bItemProcessor>oh-from(job, nencrpa些>nahopjjp= 得知titlfon t><-align:beans nt><-align:beansns:bnew a;obLyL BeanValignhu:bItemProcessorts Perslltid" 和 iher ro继obL beanValignhu:bItemProcessor>oyL 和 iher ro继a t>nthrowfbLyL Exceptull cher.ru 使 /业Ca ns:bBeanValignhu:bItemProcessorts Perslltid"beanValignhu:bItemProcessor = <和 iher ro继yLtid">nnewbLyL BeanValignhu:bItemProcessorts tid"(); 使 /业Ca ns:bbeanValignhu:bItemProcessor.setFiljer( 和 iher ro继yLtid">ntruebLyL); 使 /业Ca 使 /业Ca ns:b<和 iher ro继yLtid">nreturn aryLbeanValignhu:bItemProcessor; 使 /业Ca } <-align:beans容易 ><-align:b容易 ><-align:b nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<防止国家持续存在<-align:beans nt><-align:beansns:b h5的/f gONED任l-aliItemReader>oh-from> h5的/foac&inherit;"t><理域对象<和t/ nt>gONED任l-aliItemWljer>oh-from(job, oh-from(job, ne以指示是否已对其进行处理 .incrpa些>n特定记录时>ne已处理标志从翻转oh-from(job, neSQL语句可以在oh-from(job, ne例如oh-from(job, ne例如当前行号>ne因为它与重新启动无关 .incrpa些>ne所有读者和作家都包含“ saveState”属性>ne如以>hebLa所示ahopjjp= 得知titlfon t><-align:beans nt>&idisplay: none;jallt><-align:beansns:b ts aunch-fromname">bean aryL aunch-fromattr">idbLyL=<和 iher ro继sto">playerSummarizaaullSourcei aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spo...JdbcCurslrItemReaderi aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">gnheSourcei aryL aunch-fromattr">abLyL=<和 iher ro继sto">gnheSourcei aryL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">rowMapperi aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">bean aryL aunch-fromattr">nch-fbLyL=<和 iher ro继sto">org.spoft>oyL <和 iher ro继ta">ts / aunch-fromname">property aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">saveStatei aryL aunch-fromattr">valuebLyL=<和 iher ro继sto">falsei aryL/tid">oyL <和 iher ro继ta">ts aunch-fromname">property aryL aunch-fromattr">namebLyL=<和 iher ro继sto">sqli aryLtid">oyL <和 iher ro继ta">ts aunch-fromname">valuebLyLtid">oyL opjjp= incrr/> SELECT games.player_id, games.year_no, SUM(COMPLETES), opjjp= incrr/> SUM(ATTEMPTS), SUM(PASSING_YARDS), SUM(PASSING_TD), opjjp= incrr/> SUM(INTERCEPTIONS), SUM(RUSHES), SUM(RUSH_YARDS), opjjp= incrr/> SUM(RECEPTIONS), SUM(RECEPTIONS_YARDS), SUM(TOTAL_TD) opjjp= incrr/> fromgames, players wip e players.player_id = opjjp= incrr/> games.player_id group by games.player_id, games.year_no opjjp= incrr/<和 iher ro继ta">ts / aunch-fromname">valuebLyLtid">oyL <和 iher ro继ta">ts / aunch-fromname">property aryLtid">oyL <和 iher ro继ta">ts / aunch-fromname">bean aryLtid">oyL <-align:beans容易 ><-align:beans nt><-align:beansns:b&inherit;"t><理域对象< .incrpan>&inherit;"t><理域对象<-align:beansns:bnew a;obLyL JdbcCurslrItemReader 和 iher ro继obL playerSummarizaaullSource>oyL 和 iher ro继a t>nreturn aryL<和 iher ro继yLtid">nnewbLyL JdbcCurslrItemReaderBuilderts PlayerSummarytid"() 使 /业Ca .gnheSource(gnheSource) 使 /业Ca .rowMapper(<和 iher ro继yLtid">nnewbLyL PlayerSummaryMapper()) 使 /业Ca .saveState(<和 iher ro继yLtid">nfalse>oyL) 使 /业Ca .sql(<和 iher ro继sto">SELECT games.player_id, games.year_no, SUM(COMPLETES),i aryL +<和 iher ro继sto">SUM(ATTEMPTS), SUM(PASSING_YARDS), SUM(PASSING_TD),i aryL +<和 iher ro继sto">SUM(INTERCEPTIONS), SUM(RUSHES), SUM(RUSH_YARDS),i aryL +<和 iher ro继sto">SUM(RECEPTIONS), SUM(RECEPTIONS_YARDS), SUM(TOTAL_TD)i aryL +<和 iher ro继sto">fromgames, players wip e players.player_id =i aryL +<和 iher ro继sto">games.player_id group by games.player_id, games.year_no">oyL) 使 /业Ca .build(); 使 /业Ca 使 /业Ca } <-align:beans容易 ><-align:beans nt><-align:beansns:b h5的/f oh-from> h5的/foac&inherit;"t><理域对象<述构成会住在任何条目hopjjp= l-aliExecutullC lax >oh-from(job, h任何执行 .incrpa些 得知titlfon t><-align:b容易 ><-align:b nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<创建自定义ItemReaders和ItemWljers<-align:beans nt><-align:beansns:b h5的/f ne开箱即phebCR实现可能无法涵盖许多潜在bCR场景 .incrpa些>gONED任l-aliItemReader>oh-from> h5的/foac&inherit;"t><理域对象<和t/ nt>gONED任l-aliItemWljer>oh-from(job, &inherit;"t><理域对象<该titlfon t>gONED任l-aliItemReader>oh-from> h5的/foac&inherit;"t><理域对象<还器具 nt>gONED任l-aliItemStream>oh-from(job, ne以说明如何让读者或作家重新启动 .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<自订 nt>gONED任l-aliItemReader>oh-from> h5的/foac&inherit;"t><理域对象<范<-align:beansns:b<-align:beansns:bean;tpM> h5的/f gONED任l-aliItemReader>oh-from> h5的/foac&inherit;"t><理域对象<实p>ne该实现从提供的列表读取 .incrpa些><-align:beansns:bean;t nt>gONED任l-aliItemReader>oh-from> h5的/foac&inherit;"t><理域对象<>ne该t nt>gONED任l-aliread>oh-from(job, ne如在下面的码ahopjjp= 得知titlfon t><-align:beans <-align:beansns:b new a;obLyL <和 iher ro继iher nnch-fbLyL 和 iher ro继obL CustomItemReader>oaryLts aunch-fromobL T aryLtid" 和 iher ro继yLtid">nimpeama fbLyL 和 iher ro继obL ItemReader>oaryLts aunch-fromobL T aryLtid" cher.ru 使 /业Ca 使 /业Ca ns:bLjn ts Ttid"items; 使 /业Ca 使 /业Ca ns:b<和 iher ro继Suchaullig<和 iher ro继yLtid">new a;obLyL 和 iher ro继obL CustomItemReader>oaryL 和 iher ro继a t>nthifbLyL.items =items; 使 /业Ca bs:b} 使 /业Ca 使 /业Ca ns:b<和 iher ro继Suchaullig<和 iher ro继yLtid">new a;obLyL T 和 iher ro继obL read>oaryL 和 iher ro继a t>nthrowfbLyL Exceptull, Unexpn edInputExceptull, ns:bs:NonTransia ResourceExceptull, ParseExceptull cher.ru 使 /业Ca opjjp= incrr/<和 iher ro继yLtid">nibLyL (!items.isEmpty()) { ><-align:b和 iher ro继yLtid">nreturn aryLitems.remove(<和 iher ro继numberig0bLyL); 使 /业Ca -align:b} opjjp= incrr/<和 iher ro继yLtid">nreturn aryL<和 iher ro继yLtid">nnull>oaryL; 使 /业Ca bs:b} 使 /业Ca } <-align:beans <容易 ><-align:beans <-align:beansns:bean;tpM> h5的/f ne将其从列表删除 .incrpa些>gONED任l-alinull>oh-from(job, oh-from> h5的/foac&inherit;"t><理域对象<>ne如以>he测试代码所示ahopjjp= 得知titlfon t><-align:beans <-align:beansns:b nnewbLyL ArrayLjn ts tid"(); 使 /业Ca items.add(<和 iher ro继sto">1i aryL); 使 /业Ca items.add(<和 iher ro继sto">2i aryL); 使 /业Ca items.add(<和 iher ro继sto">3i aryL); 使 /业Ca 使 /业Ca ItemReaderitemReader = <和 iher ro继yLtid">nnewbLyL CustomItemReaderts tid"(items); 使 /业Ca er herEquals(<和 iher ro继sto">1i aryL,itemReader.read()); 使 /业Ca er herEquals(<和 iher ro继sto">2i aryL,itemReader.read()); 使 /业Ca er herEquals(<和 iher ro继sto">3i aryL,itemReader.read()); 使 /业Ca er herNull(itemReader.read()); <-align:beans <容易 ><-align:beans <-align:beansns:b Joo hunk } : e e>Jo系轻- } h5的/f oh-from> h5的/foac&inherit;"t><理域对象<重启<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliItemReader>oh-from> h5的/foac&inherit;"t><理域对象<可重启 .incrpa些>oh-from> h5的/foac&inherit;"t><理域对象<必须>头开始 .incrpa些>ne但有时最好将批处理作业>中断处重新开始 .incrpa些>ne但是有状态读取器必须尝试在重新启动时重新构造其最后hull已知状态 .incrpa些>ne我们建议您尽可能自定义阅读器保持无状态>ne因此您不必担心可重新启动性 .incrpa些 得知titlfon t><-align:beans <-align:beansns:bean; h5的/f ne nt>gONED任l-aliItemStream>oh-from(job, g>&inherit;"t><理域对象<接口>nahopjjp= 得知titlfon t><-align:beans <-align:beansns:b new a;obLyL <和 iher ro继iher nnch-fbLyL 和 iher ro继obL CustomItemReader>oaryLts aunch-fromobL T aryLtid" 和 iher ro继yLtid">nimpeama fbLyL 和 iher ro继obL ItemReader>oaryLts aunch-fromobL T aryLtid", 和 iher ro继obL ItemStream>oaryL cher.ru 使 /业Ca 使 /业Ca ns:bLjn ts Ttid"items; 使 /业Ca <和 iher ro继yLtid">nint>oaryLcurra Iean = <和 iher ro继numberig0bLyL; ns:b<和 iher ro继yLtid">nerivnhe>oyL <和 iher ro继yLtid">nstat;obLyL <和 iher ro继yLtid">nfinal>oaryL Sto CURRENT_INDEX = <和 iher ro继sto">curra .tean">oaryL; 使 /业Ca 使 /业Ca ns:b<和 iher ro继Suchaullig<和 iher ro继yLtid">new a;obLyL 和 iher ro继obL CustomItemReader>oaryL 和 iher ro继a t>nthifbLyL.items =items; 使 /业Ca bs:b} 使 /业Ca 使 /业Ca ns:b<和 iher ro继Suchaullig<和 iher ro继yLtid">new a;obLyL T 和 iher ro继obL read>oaryL 和 iher ro继a t>nthrowfbLyL Exceptull, Unexpn edInputExceptull, ns:bs: ParseExceptull,:NonTransia ResourceExceptull cher.ru 使 /业Ca opjjp= incrr/<和 iher ro继yLtid">nibLyL (curra Iean ts items.size()) { ><-align:b和 iher ro继yLtid">nreturn aryLitems.get(curra Iean++); 使 /业Ca -align:b} opjjp= opjjp= incrr/<和 iher ro继yLtid">nreturn aryL<和 iher ro继yLtid">nnull>oaryL; 使 /业Ca bs:b} 使 /业Ca 使 /业Ca ns:b<和 iher ro继Suchaullig<和 iher ro继yLtid">new a;obLyL 和 iher ro继yLtid">nvoidbLyL 和 iher ro继obL opel aryL 和 iher ro继a t>nthrowfbLyL ItemStreamExceptull cher.ru incrr/<和 iher ro继yLtid">nibLyL(executullC lax .R lainsKey(CURRENT_INDEX))u 使 /业Ca ns:bbbbbbbbbcurra Iean = <和 iher ro继yLtid">nnewbLyL Long(executullC lax .getLong(CURRENT_INDEX)).i lValue(); 使 /业Ca ns:bbs:b} 使 /业Ca incrr/<和 iher ro继yLtid">nelse>oyLu 使 /业Ca ns:bbbbbbbbbcurra Iean = <和 iher ro继numberig0bLyL; 使 /业Ca ns:bbs:b} 使 /业Ca incr} 使 /业Ca 使 /业Ca ns:b<和 iher ro继Suchaullig<和 iher ro继yLtid">new a;obLyL 和 iher ro继yLtid">nvoidbLyL 和 iher ro继obL upgnhe>oyL 和 iher ro继a t>nthrowfbLyL ItemStreamExceptull cher.ru 使 /业Ca ns:bbs:bexecutullC lax .putLong(CURRENT_INDEX, 和 iher ro继yLtid">nnewbLyL Long(curra Iean).loValue()); 使 /业Ca incr} 使 /业Ca 使 /业Ca ns:b<和 iher ro继Suchaullig<和 iher ro继yLtid">new a;obLyL 和 iher ro继yLtid">nvoidbLyL 和 iher ro继obL closebLyL 和 iher ro继a t>nthrowfbLyL ItemStreamExceptull cher.ru} 使 /业Ca } <-align:beans <容易 ><-align:beans <-align:beansns:bean; h5的/f gONED任l-aliItemStream>oh-fro l-aliupgnhe>oh-from(job, ne的当前索引ncrpa些ONED任l-aliItemReader>oh-from> h5的/foac&inherit;"t><理域对象<-align:beansns:bean; 都存储在提供hopjjp= l-aliExecutullC lax >oh-from(job, oh-fro l-aliopel h-from> h5的/foac&inherit;"t><理域对象<调phencrpa些 .incrpan>&inherit;"t><理域对象<该titlfon t>&inherit;"t><理域对象<方法时>ne将hopjjp= l-aliExecutullC lax >oh-from(job, ne以查看它是否包含具有该键的条目 .incrpa些>ne但仍然符合h般约定>nahopjjp= 得知titlfon t><-align:beans <-align:beansns:b nnewbLyL ExecutullC lax (); 使 /业Ca ((ItemStream)itemReader).opel(executullC lax ); 使 /业Ca er herEquals(<和 iher ro继sto">1i aryL,itemReader.read()); 使 /业Ca ((ItemStream)itemReader).upgnhe(executullC lax ); 使 /业Ca 使 /业Ca Ljn ts Stotid"items = <和 iher ro继yLtid">nnewbLyL ArrayLjn ts tid"(); 使 /业Ca items.add(<和 iher ro继sto">1i aryL); 使 /业Ca items.add(<和 iher ro继sto">2i aryL); 使 /业Ca items.add(<和 iher ro继sto">3i aryL); 使 /业Ca itemReader = <和 iher ro继yLtid">nnewbLyL CustomItemReaderts tid"(items); 使 /业Ca 使 /业Ca ((ItemStream)itemReader).opel(executullC lax ); 使 /业Ca er herEquals(<和 iher ro继sto">2i aryL,itemReader.read()); <-align:beans <容易 ><-align:beans <-align:beansns:bean; h5的/f oh-from> h5的/foac&inherit;"t><理域对象<都具有更复杂的重启逻辑 .incrpa些>oh-from(job, <-align:beans <-align:beansns:bean; h5的/f gONED任l-aliExecutullC lax >oh-from(job, gONED任l-aliExecutullC lax >oh-from(job, gONED任l-aliItemStreams>oh-from> h5的/foac&inherit;"t><理域对象<内 nt>gONED任l-aliStepbLh-from(job, 证唯h性 .incrpa些>gONED任l-aliItemStream>oh-from(job, g>&inherit;"t><理域对象<文件>n如果需要两ull文件进行输出l-则可能发生这种情况)l-则需要一ull更唯h的名称 .incrpa些>ne许多Spo Batchtitlfon t>oh-from> h5的/foac&inherit;"t><理域对象<和t/ nt>gONED任l-aliItemWljer>oh-from(job, ne可以覆盖此键名 .incrpa些 得知titlfon t><-align:beans 容易 ><-align:beans容易 ><-align:beans nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<自订 nt>gONED任l-aliItemWljer>oh-from(job, <-align:beansns:b<-align:beansns:bean;tpM> h5的/f gONED任l-aliItemWljer>oh-from(job, h上述oh-from> h5的/foac&inherit;"t><理域对象nencrpa些>ne因此在本La中未涉及 .incrpa些><-align:beansns:bean;t nt>gONED任l-aliItemReader>oh-from> h5的/foac&inherit;"t><理域对象ne住phea;t nt>gONED任l-aliLjn >oh-from(job, <-align:beans <-align:beansns:b new a;obLyL <和 iher ro继iher nnch-fbLyL 和 iher ro继obL CustomItemWljer>oaryLts aunch-fromobL T aryLtid" 和 iher ro继yLtid">nimpeama fbLyL 和 iher ro继obL ItemWljer>oaryLts aunch-fromobL T aryLtid" cher.ru 使 /业Ca 使 /业Ca ns:bLjn ts Ttid"outpu = TransahaullAwareProxyFahaory.createTransahaullalLjn (); 使 /业Ca 使 /业Ca <和 iher ro继Suchaullig<和 iher ro继yLtid">new a;obLyL 和 iher ro继yLtid">nvoidbLyL 和 iher ro继obL wlje>oaryL 和 iher ro继a t>nthrowfbLyL Exceptull cher.ru 使 /业Ca ns:bbs:boutpu .addAll(items); 使 /业Ca bs:b} 使 /业Ca 使 /业Ca ns:b<和 iher ro继Suchaullig<和 iher ro继yLtid">new a;obLyL Ljn ts Ttid" 和 iher ro继obL getOutpu bLyL 和 iher ro继a t>nreturn aryLoutpu ; 使 /业Ca bs:b} 使 /业Ca } <-align:beans <容易 ><-align:beans <-align:beansns:b Joo hunk } : e e>Jo系轻- } h5的/f oh-from(job, <-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliItemWljer>oh-from(job, ne我们将按照与相同的过程进行操作titlfon t>oh-from> h5的/foac&inherit;"t><理域对象gONED任l-aliItemStream>oh-from(job, ne我们可能必须计算已处理的项目数并将其添加页脚记录 .incrpa些>gONED任l-aliItemStream>oh-from(job, &inherit;"t><理域对象<, nt>gONED任l-aliItemWljer>oh-from(job, <-align:beans <-align:beansns:bean; h5的/f h5的/foac&inherit;"t><理域对象<还委派给另一ull本身可重新启动的b写器>n例如l-当写入文件时>n>ne或者它写入事务性资源>ne因此不需要重新启动>ne因为它是无状态的 .incrpa些>gONED任l-aliItemStream>oh-from(job, ne以及 nt>gONED任l-aliItemWljer>oh-from(job, ne编写者bCR客户端需要注意 nt>gONED任l-aliItemStream>oh-from(job, ne因此您可能需要将其注册为配置中的流 .incrpa些 得知titlfon t><-align:beans 容易 ><-align:beans容易 ><-align:b容易 ><-align:b nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<项目读取器和写入器实现 nt>gONED任h3易 ><-align:beans nt><-align:beansns:b h5的/f ne我们将向您介绍之前各节中未讨论的读者和作家 .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<装饰工 nt>gONED任h4易 ><-align:beansns:b<-align:beansns:bean;tpM> h5的/f <-align:beansns:bean;t nt>gONED任l-aliItemReader>oh-from> h5的/foac&inherit;"t><理域对象< .incrpa些>ne它们可以>h您oh-from> h5的/foac&inherit;"t><理域对象<和t/ nt>gONED任l-aliItemWljer>oh-from(job, &inherit;"t><理域对象<添加更多行为&inherit;"t><理域对象< .incrpa些 得知titlfon t><-align:beans <-align:beansns:bean;tpM> h5的/f he装饰器>nahopjjp= 得知titlfon t><-align:beans <-align:beansns:bean;tulallt><-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"synk ronizedItemStreamReaderi iher : e e>Jo系轻- }<-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"ss:beaItemPeekableItemReaderi iher : e e>Jo系轻- }<-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"multiResourceItemWljeri iher : e e>Jo系轻- }<-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;" ihifierComposljeItemWljeri iher : e e>Jo系轻- }<-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;" ihifierComposljeItemProcessori iher : e e>Jo系轻- }<-align:beansns:bean;<-align:beansns:b<容易 ><-align:beans <-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliItemReader>oh-from> h5的/foac&inherit;"t><理域对象<不是线程安全的时>neSpo Batch提供titlfon t> h5的/foac&inherit;"t><理域对象<装饰器>ne该装饰器可phe于 nt>gONED任l-aliItemReader>oh-from> h5的/foac&inherit;"t><理域对象<-align:beansns:bean; 线程安全 .incrpa些>oh-from(job, h5的/foac&inherit;"t><理域对象< .incrpa些 得知titlfon t><-align:beans 容易 ><-align:beans f<和 iheron 4jallt><-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f ne该装饰器将peek方法添加到oh-from> h5的/foac&inherit;"t><理域对象< .incrpa些>gONED任l-aliread>oh-from(job, &inherit;"t><理域对象< .incrpa些>oh-from(job, h5的/foac&inherit;"t><理域对象< .incrpa些 得知titlfon t><-align:beans <-align:beansns:bean; <-align:beansns:bean; ttbody><-align:beansns:bean; ttd ihericlligllt><-align:beansns:bean; ti iherfa icll-noteb obL="注意ig< i<-align:beansns:bean; t/td<-align:beansns:bean; ttd iherR la jom> h5的/foac&inherit;"t><理域对象<-align:beansns:bean; Ss:beaItemPeekableItemReaderbCRpeek方法不是线程安全的>ne因为不可能在多ull线程中住phepeek .incrpa些><-align:beansns:bean; t/rpa些 td<-align:beansns:bean; tr<-align:beansns:bean; tbody><-align:beansns:bean;<容易 ><-align:beans 容易 ><-align:beans f<和 iheron 4jallt><-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliMultiResourceItemWljer h5的/f gONED任l-aliResourceAwareItemWljerItemStream>oh-from(job, ne当写在当前资源的项目数超过了创建hull新bCR输出资源titlfon t>oh-from> h5的/foac&inherit;"t><理域对象< .incrpa些>oh-from(job, h5的/f <-align:beans 容易 ><-align:beans f<和 iheron 4jallt><-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliC ihifierComposljeItemWljer h5的/f h5的/f <-align:beansns:bean; 对每ull项目实施的基础l>ne通过提供实现bCR路由器模式titlfon t>oh-from> h5的/foac&inherit;"t><理域对象< .incrpa些>ne则实p是线程安全的 .incrpa些>oh-from(job, h5的/f <-align:beans 容易 ><-align:beans f<和 iheron 4jallt><-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliC ihifierComposljeItemProcessor ne通过提供实现bCR路由器模式oh-from> h5的/foac&inherit;"t><理域对象< .incrpa些>oh-from(job, <-align:beans 容易 ><-align:beans容易 ><-align:beans nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<消息读者和作家 nt>gONED任h4易 ><-align:beansns:b<-align:beansns:bean;tpM> h5的/f he读取器和写入器>nahopjjp= 得知titlfon t><-align:beans <-align:beansns:bean;tulallt><-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"amqpItemReaderi iher : e e>Jo系轻- }<-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"amqpItemWljeri iher : e e>Jo系轻- }<-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"jmsItemReaderi iher : e e>Jo系轻- }<-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"jmsItemWljeri iher : e e>Jo系轻- }<-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"kafkaItemReaderi iher : e e>Jo系轻- }<-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"kafkaItemWljeri iher : e e>Jo系轻- }<-align:beansns:bean;<-align:beansns:b<容易 ><-align:beans <-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliAmqpItemReader oh-from> h5的/foac&inherit;"t><理域对象<一种住phe nt>gONED任l-aliAmqpTemplnhe>oh-from(job, oh-from(job, <-align:beans 容易 ><-align:beans f<和 iheron 4jallt><-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliAmqpItemWljer h5的/f oh-from(job, gONED任l-aliAmqpTemplnhe>oh-from(job, ne则消息将发送到无名交换 nt>gONED任l-aliAmqpTemplnhe>oh-from(job, gONED任l-aliAmqpItemWljerBuilder>oh-from(job, h5的/f <-align:beans 容易 ><-align:beans f<和 iheron 4jallt><-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliJmsItemReader oh-from> h5的/foac&inherit;"t><理域对象<对JMSphehullncrpa些ONED任l-aliJmsTemplnhe>oh-from(job, ne该目标phe于提供hopjjp= l-aliread() h5的/f <-align:beansns:bean; 方法的 nt>g>&inherit;"t><理域对象< .incrpa些>gONED任l-aliJmsItemReaderBuilder>oh-from(job, <-align:beans 容易 ><-align:beans f<和 iheron 4jallt><-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliJmsItemWljer h5的/f oh-from(job, oh-from(job, ne该目标phe于发送h的项目 h5的/f gONED任l-aliJmsItemWljerBuilder>oh-from(job, h5的/f <-align:beans 容易 ><-align:beans f<和 iheron 4jallt><-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliKafkaItemReader oh-from> h5的/foac&inherit;"t><理域对象<对hullApache卡夫卡的话题 .incrpa些>oh-from(job, <-align:beans 容易 ><-align:beans f<和 iheron 4jallt><-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliKafkaItemWljer h5的/f oh-from(job, oh-from(job, gONED任l-aliKafkaItemWljerBuilder>oh-from(job, h5的/f <-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<数据库读者 nt>gONED任h4易 ><-align:beansns:b<-align:beansns:bean;tpM> h5的/f he数据库阅读器>nahopjjp= 得知titlfon t><-align:beans <-align:beansns:bean;tulallt><-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"Neo4jItemReaderi iher : e e>Jo系轻- }<-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"mongoItemReaderi iher : e e>Jo系轻- }<-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"hibernnheCurslrItemReaderi iher : e e>Jo系轻- }<-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"hibernnhePagItemReaderi iher : e e>Jo系轻- }<-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"reposljoryItemReaderi iher : e e>Jo系轻- }<-align:beansns:bean;<-align:beansns:b<容易 ><-align:beans <-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliNeo4jItemReader oh-from> h5的/foac&inherit;"t><理域对象<>ne通过phe寻呼技术读取从图形数据库Neo4jbCR对象 .incrpa些>gONED任l-aliNeo4jItemReaderBuilder>oh-from(job, <-align:beans 容易 ><-align:beans f<和 iheron 4jallt><-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliMongoItemReader oh-from> h5的/foac&inherit;"t><理域对象<>ne通过phe寻呼技术读取MongoDB的文档 .incrpa些>oh-from(job, <-align:beans 容易 ><-align:beans f<和 iheron 4jallt><-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliHibernnheCurslrItemReader h5的/foac&inherit;"t><理域对象 h5的/f g>ne依次返回与当前行相对应bCR对象 .incrpa些>oh-from(job, <-align:beans 容易 ><-align:beans f<和 iheron 4jallt><-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliHibernnhePagItemReader h5的/foac&inherit;"t><理域对象ne并在同h时间只读取到hull固定数量的项目 .incrpa些>oh-from(job, <-align:beans 容易 ><-align:beans f<和 iheron 4jallt><-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliReposljoryItemReader oh-from> h5的/foac&inherit;"t><理域对象<>ne通过phe读取记录titlfon t> h5的/f gONED任l-aliReposljoryItemReaderBuilder>oh-from(job, <-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<数据库作家 nt>gONED任h4易 ><-align:beansns:b<-align:beansns:bean;tpM> h5的/f he数据库b写器>nahopjjp= 得知titlfon t><-align:beans <-align:beansns:bean;tulallt><-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"neo4jItemWljeri iher : e e>Jo系轻- }<-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"mongoItemWljeri iher : e e>Jo系轻- }<-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"reposljoryItemWljeri iher : e e>Jo系轻- }<-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"hibernnheItemWljeri iher : e e>Jo系轻- }<-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"jdbcBatchItemWljeri iher : e e>Jo系轻- }<-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"jpaItemWljeri iher : e e>Jo系轻- }<-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"gemfireItemWljeri iher : e e>Jo系轻- }<-align:beansns:bean;<-align:beansns:b<容易 ><-align:beans <-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f h5的/f oh-from(job, gONED任l-aliNeo4jItemWljerBuilder>oh-from(job, h5的/f <-align:beans 容易 ><-align:beans f<和 iheron 4jallt><-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliMongoItemWljer h5的/f oh-from(job, gONED任l-aliMongoOperaaulls h5的/f oh-from(job, h5的/f <-align:beans 容易 ><-align:beans f<和 iheron 4jallt><-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliReposljoryItemWljer h5的/f oh-from(job, h5的/f ne从春天的数据 .incrpa些>gONED任l-aliReposljoryItemWljerBuilder>oh-from(job, h5的/f <-align:beans 容易 ><-align:beans f<和 iheron 4jallt><-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliHibernnheItemWljer h5的/f oh-from(job, oh-from(job, h5的/f <-align:beans 容易 ><-align:beans f<和 iheron 4jallt><-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliJdbcBatchItemWljer h5的/f oh-from(job, ne它phe批处理功能从titlfon t>oh-from(job, gONED任l-aliJdbcBatchItemWljerBuilder>oh-from(job, h5的/f <-align:beans 容易 ><-align:beans f<和 iheron 4jallt><-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliJpaItemWljer h5的/f h5的/f h5的/f oh-from(job, h5的/f <-align:beans 容易 ><-align:beans f<和 iheron 4jallt><-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliGemfireItemWljer h5的/f oh-from(job, ne它phellncrpa些ONED任l-aliGemfireTemplnhe>oh-from(job, ne在存储的GemFire的项目>ne如键/值对 .incrpa些>gONED任l-aliGemfireItemWljerBuilder>oh-from(job, <-align:beansns:bean; 来构造bCR实 h5的/f <-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<专业读者 nt>gONED任h4易 ><-align:beansns:b<-align:beansns:bean;tpM> h5的/f he专业读者>nahopjjp= 得知titlfon t><-align:beans <-align:beansns:bean;tulallt><-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"ldifReaderi iher : e e>Jo系轻- }<-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"mapps:bLdifReaderi iher : e e>Jo系轻- }<-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"avroItemReaderi iher : e e>Jo系轻- }<-align:beansns:bean;<-align:beansns:b<容易 ><-align:beans <-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f h5的/f oh-from(job, ne解析它>ne并oh-from(job, gONED任l-aliread>oh-from(job, g .incrpan>&inherit;"t><理域对象<的 nt>g>g>g>g>gONED任l-aliLdifReaderBuilder>oh-from(job, h5的/f <-align:beans 容易 ><-align:beans f<和 iheron 4jallt><-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f h5的/f oh-from(job, ne对其进行解析,然后将每ullLDIF记录映射到POJO(普通旧Java对象) .incrpa些>oh-from(job, h5的/f <-align:beans 容易 ><-align:beans f<和 iheron 4jallt><-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliAvroItemReader h5的/f ne以输入是否嵌入Avro模式 .incrpa些>gONED任l-aliAvroItemReaderBuilder>oh-from(job, h5的/f <-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<专业作家 nt>gONED任h4易 ><-align:beansns:b<-align:beansns:bean;tpM> h5的/f he专业作家>nahopjjp= 得知titlfon t><-align:beans <-align:beansns:bean;tulallt><-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"simpleMailMessageItemWljeri iher : e e>Jo系轻- }<-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"avroItemWljeri iher : e e>Jo系轻- }<-align:beansns:bean;<-align:beansns:b<容易 ><-align:beans <-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliSimpleMailMessageItemWljer oh-from(job, ne可以发送邮件 .incrpa些> h5的/f oh-from(job, <-align:beans 容易 ><-align:beans f<和 iheron 4jallt><-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f oh-from(job, gONED任l-aliAvroItemWljerBuilder>oh-from(job, <-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<专phe处理器hopjjp= h4易 ><-align:beansns:b<-align:beansns:bean;tpM> h5的/f he专phe处理器>nahopjjp= 得知titlfon t><-align:beans <-align:beansns:bean;tulallt><-align:beansns:bean; <-align:beansns:bean; tpMaataerteansns:bean; n;"scriptItemProcessori iher : e e>Jo系轻- }<-align:beansns:bean;<-align:beansns:b<容易 ><-align:beans <-align:beansns:b Joo hunk } : e e>Jo系轻- }<-align:beansns:b <-align:beansns:bean; h5的/f gONED任l-aliScriptItemProcessor oh-from(job, <-align:beans 容易 ><-align:beans容易 ><-align:b容易 ><-ali容易 ><容易 ><-aliJoo hunk } : e e>Jo系轻- } h5的/f <-ali<-align:b<-align:beans h5的/f ne单流程作业可以解决许多批处理问题>ne因此在考虑更复杂bCR实现之前>ne适当地检查是否满足您的需求始终是ll好主意 .incrpa些>ne并查看最简单CR实现是否首先满足您的需求 .incrpa些>ne您也可以e分钟之内轻松读写数百兆的文件 .incrpa些 得知titlfon t>容易 ><-align:bf<和 iher a;obL<-align:beans h5的/f neSpo Batch提供h系列选项>ne本b对此进行绍>ne尽管其他地方绍hu功能 .incrpa些>ne有两种并行处理模式>nahopjjp= 得知titlfon t>容易 ><-align:bf<和 iherurjn ballt><-align:beanstulallt><-align:beansns:b<-align:beansns:bean; h5的/f ne多线程hopjjp= 得知titlfon t><-align:beansns:b<-align:beansns:bean; h5的/f <-align:beans<-align:b容易 ><-align:bf<和 iher a;obL<-align:beans h5的/f he几类>nahopjjp= 得知titlfon t>容易 ><-align:bf<和 iherurjn ballt><-align:beanstulallt><-align:beansns:b<-align:beansns:bean; h5的/f nhopjjp= 得知titlfon t><-align:beansns:b<-align:beansns:bean; h5的/f nhopjjp= 得知titlfon t><-align:beansns:b<-align:beansns:bean; h5的/f nhopjjp= 得知titlfon t><-align:beansns:b<-align:beansns:bean; h5的/f nhopjjp= 得知titlfon t><-align:beans<-align:b容易 ><-align:bf<和 iher a;obL<-align:beans h5的/f ne我们回顾l单进程选项 .incrpa些>ne我们回顾多进程选项 .incrpa些 得知titlfon t>容易 ><-align:bf<和 iheron 2ballt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<多线程步骤hopjjp= h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f g><-align:bgn:b nt><-align:beansns:bF} example, you might add an attribuhe of the l-alitasklet <-align:beansns:bean;follow example:得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt> <span nt>step span nt>id=span nt>"load">/span> ><span nt>tasklet span nt>task-executor =span nt>"taskExecutor">/span>...span nt></span nt>tasklet >/span>span nt></span nt>step>/span> <-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f nehe示例所示>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt><-align:beans public TaskExecutor span nt>() { >return span nt>new SimpleAsyncTaskExecutor(span nt>"spo_batch");span nt>public Step span nt>(TaskExecutor { span nt>return span nt>this/span>.stepBuilderFacjory.get(span nt>"sampleStep"))<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f negONED任l-aliTaskExecutor g>g><-align:beans nt>gONED任aataerhttps://docs.spo.io/spo/docs/current/javadoc-api/org/spof;omeworkJo系轻- } h5的/f <-align:beansns:bean;是标准的Spo界面>ne因此请查阅《 Spo用户指南》以获取可phe实现的详细信息 .incrpa些><-align:beans nt>gONED任l-aliSimpleAsyncTaskExecutor <-align:bgn:b nt><-align:beansns:b h5的/f h配置bCR结果是ne处理和写入每ull项目块(每ull提交间隔)来执行 .incrpa些>ne这意味着要处理的项目没有固定bCR顺序>ne与单线程情况相比>ne大块可能包含不连续的项目 .incrpa些>n例如>ne是否由线程池支持)之外>netasklet配置中还有一ull限制值>ne默认为4.您可能需要增加此限制确保线程池是充分利phe .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansns:bF} example you might increase the throttle-limit, as shown<-align:bgn:b nt><-align:beansns:b< nt> <span nt>step span nt>id=span nt>"load">/span><span nt>tasklet >task-executor =span nt>"taskExecutor" >throttle-limit =span nt>"20">/span>...span nt></span nt>tasklet >/span>span nt></span nt>step>/span> <-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne构建器提供对油门限制的访问>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt><-align:beansns:b< nt>public Step span nt>(TaskExecutor { span nt>return span nt>this/span>.stepBuilderFacjory.get(span nt>"sampleStep")))<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne您的步骤中phebCR所有池化资源>n例如>n可能会限制并发性oh-from(job, <-align:bgn:b nt><-align:beansns:b h5的/f ne住phe多线程hopjjp=>g>g>gONED任l-aliStepn例如读者和作家>n都是有状态bCR .incrpa些>ne则这uR不能e多线程中phe nt>gONED任l-aliStepneSpo BatchCR大多数现成的读写器都不是为多线程住phe而设计bCR .incrpa些>ne可以与无状态或线程安全的读取器和写入器起住phe>ne并且gONED任aataerhttps://github.com/spo-projects/spo-batch/tree/master/spo-batch-samplesi iher : e e>Jo系轻- }gOaM> h5的/f n称为 nt>gONED任l-ali a;ollelJobn>ne该 ><-align:beans nt>gONED任aataerhttps://github.com/spo-projects/spo-batch/tree/master/spo-batch-samplesi iher : e e>Jo系轻- } h5的/f n请参见 ><-align:beans nt>gONED任aataerteansns:bean; n;"process-teatori iher : e e>Jo系轻- } h5的/f <-align:bgn:b nt><-align:beansns:b h5的/f gONED任l-aliItemWljer g>gONED任l-aliItemReader h5的/f ne他们eJavaeta中说出它是否是线程安全的>ne或者为避免e并发环境h发生问题而必须采取bCR措施 .incrpa些>ne则可以检查实现以查看是否存e何状态 .incrpa些>ne则可以用提供的装饰器将其装饰>ne h5的/f nenencrpa些><-align:b容易 ><-align:bf<和 iheron 2ballt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<平行步骤hopjjp= h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f <-align:bgn:b nt><-align:beansns:bF} example, execut steps l-ali(step1,step2) <-align:beansns:bean;as shown<-align:bgn:b nt><-align:beansns:b< nt> <span nt>job span nt>id=span nt>"job1">/span> ><span nt>split span nt>id=span nt>"split1"task-executor =span nt>"taskExecutor"next =span nt>"step4">/span> >< ><span nt>flow>/span> >< >< ><span nt>step span nt>id=span nt>"step1" a;ent=span nt>"s1"next =span nt>"step2"/>/span> >< >< ><span nt>step span nt>id=span nt>"step2" a;ent=span nt>"s2"/>/span> >< ></span nt>flow>/span> >< ><span nt>flow>/span> >< >< ><span nt>step span nt>id=span nt>"step3" a;ent=span nt>"s3"/>/span> >< ></span nt>flow>/span> ></span nt>split >/span> ><span nt>step span nt>id=span nt>"step4" a;ent=span nt>"s4"/>/span>span nt></span nt>job>/span> opjjp= <span nt>beans:bean/span> span nt>id=span nt>"taskExecutor"nt><=span nt>"org.spo...SimpleAsyncTaskExecutor"/>/span> <-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne h5的/f h5的/f <-align:beansns:bean;非常简单e如>he示例所示>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt><-align:beansns:b< nt>public Job span nt>() {ns:breturn jobBuilderFacjory.get(span nt>"job")ospan> >< ><.build();ansns:bospan>span nt>public Flow span nt>() {ns:breturn span nt>new FlowBuilder<SimpleFlow>(span nt>"splitFlow")span nt>public Flow span nt>() {ns:breturn span nt>new FlowBuilder<SimpleFlow>(span nt>"flow1")span nt>public Flow span nt>() {ns:breturn span nt>new FlowBuilder<SimpleFlow>(span nt>"flow2")span nt>public TaskExecutor span nt>() { >return span nt>new SimpleAsyncTaskExecutor(span nt>"spo_batch");<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f <-align:beansns:bean;应phe nt>g><-align:beans nt>gONED任l-aliSyncTaskExecutor ne但需要异步hopjjp= l-aliTaskExecutor ne该作业可确保拆分hbCR每ull流在汇总出口状态和过渡之前e成 .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansns:b h5的/f nencrpa些>gONED任aataerteansns:bean; n;"split-flowsi iher : e e>Jo系轻- } h5的/f g><-align:b容易 ><-align:bf<和 iheron 2ballt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<远程分块hopjjp= h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f nen并通过某种中间件相互通信 .incrpa些>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt><-align:beansns:b 远程分块ballt><-align:beansns:b<容易 ><-align:beansns:b< nt><f<titleg><foftory;/   jd予想t><aunch-f结><foftory;/   jd予想t><aunch-f结图22.远程分块hopjjp=      容易 ><-align:beans容易 ><-align:bgn:b nt><f< a;obL<ballt><-align:beansns:b<pM>
  h5的/f  </dalignlassljdg><foftory;/tica   t><aunch-f结管理器R是单ll进程>n而工作器是多ll远程进程 .incrpa些><foftory;/tica     ory;/tip
<t, 如果管理者不是瓶颈>ne则此模式最有效>ne因此处理必须比读取项目更昂贵(e实践中通常如此) .incrpa些      得知titlfon t><Mag容易 ><-align:bgn:b nt><f< a;obL<ballt><-align:beansns:b<pM>
  h5的/f  </dalignlassljdg><foftory;/tica     ory;/tip
<t, 经理是llSpo批次CR实现</rpa些ONED任l-aliStep</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结与t  nt>gONED任l-aliItemWljer <eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结替换>ne它知道如发送项目CR块到中间件作为消息的通pheb本 .incrpa些><foftory;/tica     ory;/tip
<t, 工人是正ephebCR何中间件CR标准侦听器>n例如>ne对于JMS>ne它们将是</rpa些ONED任l-aliMesssageLis ener <eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结实现>n>ne并且它们bCR用是</rpa些><foftory;/   jd予想t><aunch-f结通过</rpa些><foftory;/tica   t><aunch-f结接口ncrpa些><foftory;/tica     ory;/tip
<t, 住phe标准t  nt>gONED任l-aliItemWljer <eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结或t  nt>gONED任l-aliItemProcessor <eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结plus ><-align:beans      nt>g><foftory;/   jd予想t><aunch-f结处理项目CR大块t  nt>g><foftory;/tica   t><aunch-f结 .incrpa些><foftory;/tica     ory;/tip
<t, 住phe此模式bCR点之一是读取器>ne处理器和写入器R都是现成的>n与phe步骤的本地执行CR组件相同) .incrpa些 .incrpan>&inherit;<理域对象<这u项目是动态划分的>ne并且通过中间件共享工作>ne因此e如果侦听器都是渴望bCRphe者e那u负载平衡是自动bCR .incrpa些ONED任l-aliItemWljer <-align:bgn:b nt><-align:beansns:b h5的/f ne并且要保证传递CR可靠性>ne并且每ull消息都由llphe者来承担 .incrpa些 .incrpan>&inherit;"t><理域对象n例如JavaSpaces) .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansns:b h5的/f <-align:beansns:bean;更多详细信息>nencrpa些>gONED任aataerteansns:bean; n;"remote-chunki iher : e e>Jo系轻- } h5的/f <-align:beans nt>g><-align:b容易 ><-align:bf<和 iheron 2ballt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<分区hopjjp= h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f nephe划分n远程参与者是nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt><-align:beansns:b 分区概述ballt><-align:beansns:b<容易 ><-align:beansns:b< nt><f<titleg><foftory;/   jd予想t><aunch-f结><foftory;/   jd予想t><aunch-f结图23.分区hopjjp=      容易 ><-align:beans容易 ><-align:bgn:b nt><f< a;obL<ballt><-align:beansns:b<pM>
  h5的/f  </dalignlassljdgONED任l-aliJob</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结左侧ncrpa些><foftory;/tica     ory;/tip
<t, 的  nt>g><foftory;/tica   t><aunch-f结运行作为</rpa些ONED任l-aliStep</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结实ncrpa些><foftory;/tica     ory;/tip
<t, 序列>nencrpa些><foftory;/tica     ory;/tip
<t, 实之一 ><-align:beans      nt>gONED任l-aliStep</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结被标记为管理器 .incrpa些 .incrpan>&inherit;<理域对象<这张图片中CR工作人员都是CRe全相同的实>nene从而导致bCR结果相同&inherit;"t><理域对象<这u工作人员通常将成为远程服务e但也可能是本地执行线程 .incrpa些>ne也必保证传递 .incrpa些>ne并且每次g><-align:bgn:b nt><-align:beansns:b h5的/f n称为 ><-align:beans nt>gONED任l-aliPa;titionStepn和需要针对特定​​环境实现的两ull策略接口组成 .incrpa些>ne其用如面bCR序列图所示>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt><-align:beansns:b 分区SPIballt><-align:beansns:b<容易 ><-align:beansns:b< nt><f<titleg><foftory;/   jd予想t><aunch-f结><foftory;/   jd予想t><aunch-f结图24.对SPI进行分区hopjjp=      容易 ><-align:beans容易 ><-align:bgn:b nt><f< a;obL<ballt><-align:beansns:b<pM>
  h5的/f  </dalignlassljdg><foftory;/tica     ory;/tip
<t, 该hopjjp=      l-aliStep</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结在这种情况下>n右边是“远程”CR工人>ne因此e潜在的>ne有很多CR对象和或进程扮演这u角色>ne和</rpa些ONED任l-aliPa;titionStep</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结显示驱动执行 .incrpa些      得知titlfon t><Mag容易 ><-align:bgn:b nt><f< a;obL< xmlC   ent<-align:beansns:bThe;follow example shows the l-aliPa;titionStep<-align:bgn:b nt><-align:beansns:b< nt> <span nt>step span nt>id=span nt>"step1.manager">/span> ><span nt> a;tition span nt>step=span nt>"step1" a;titioner =span nt>" a;titioner">/span> >< ><span nt>handler grid-size =span nt>"10"task-executor =span nt>"taskExecutor"/>/span> ></span nt> a;tition>/span>span nt></span nt>step>/span> <-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f he示例显示了nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt><-align:beansns:b< nt>public Step span nt>() {ns:breturn stepBuilderFacjory.get(span nt>"step1.manager")"step1", a;titioner()))<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne该<-align:beansns:bean;属性可防止任务执行b序被单ll步骤的请求所饱和 .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansns:b h5的/f gONED任aataerhttps://github.com/spo-projects/spo-batch/tree/master/spo-batch-samples/src/main/resources/jobsi iher : e e>Jo系轻- }gO nt>gOaM> h5的/f <-align:beans nt>g>n请参阅 nt>gONED任l-aliPa;tition*Job.xmln .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansns:b h5的/f na a;tition0”CR分区创建步骤执行>ne依此类推 .incrpa些 .incrpan>&inherit;"t><理域对象ne许多人更喜欢将管理器步骤称为“ step1>namanager” .incrpa些>h该步骤住phe别名>n通过指定hopjjp= l-aliname <-align:beansns:bean;属性>n .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<分区处理程序hopjjp= h4易 ><-align:beansns:b< nt><-align:beansns:bns:b h5的/f <-align:beansns:bean;;;;;某种特定于结RCR格式>n如DTO>nncrpa些>g .incrpan>&inherit;"t><理域对象<到远程g>ne它可能也需要了解弹性或故障转移>ne因为在许多情况下>n这u是结RCR功能 .incrpa些>neSpo Batch始终提供独立架RCR可重启性 .incrpa些>ne只有失败的<-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f n包括简单CRRMI远程处理>nEJB远程处理>n自定义Web服务eJMS>neJava Spaces,共享内存网格>n例如Terracotta或Conchence>n和网格执行bR>n例如GridGain) .incrpa些 .incrpan>&inherit;"t><理域对象<-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f neSpo Batch确实提供h种有hebCR实现>ngONED任l-aliTaskExecutor g><-align:beansns:bns:b< nt>g><-align:beans ns:b< nt>gONED任l-aliTaskExecutorPa;titionHandler <-align:bgn:bns:b< nt><-align:beansns:bns:bThe;l-aliTaskExecutorPa;titionHandler <-align:beansns:bean;;;;;namespace shown<-align:beansns:bean;;;;;follow example:得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b< nt> <span nt>step span nt>id=span nt>"step1.manager">/span> ><span nt> a;tition span nt>step=span nt>"step1"handler =span nt>"handler"/>/span>span nt></span nt>step>/span> rpa些 <span nt>beannt><=span nt>"org.spo...TaskExecutorPa;titionHandler">/span> ><span nt> rop yname =span nt>"taskExecutor"ref =span nt>"taskExecutor"/>/span> ><span nt> rop yname =span nt>"step"ref =span nt>"step1" ><span nt> rop yname =span nt>"gridSize"value =span nt>"10"span nt></span nt>bean>/span> <-align:beans <-align:bgn:bns:b<容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f ne如图以>he示例>nahopjjp= 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b< nt><-align:beansns:bns:b< nt>public Step span nt>() {ns:breturn stepBuilderFacjory.get(span nt>"step1.manager")"step1", a;titioner())span nt>public Pa;titionHandler span nt>() {new TaskExecutorPa;titionHandler(););ns:breturn retVal;<-align:beans ns:b<容易 ><-align:bgn:bns:b<容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f ne因此可以>h中CR线程池大小匹配 nt>gONED任l-aliTaskExecutor ne从而使工作块变小 .incrpa些 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f n例如>ne复制大量文或将文系统复制到内容管理系统中>n>nencrpa些>g>n例如>nepheSpo Remot>n>nencrpa些>g><-align:bgn:b容易 ><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<隔断hopjjp= h4易 ><-align:beansns:b< nt><-align:beansns:bns:b h5的/f he文为输入参数生成>ne仅phe新步骤执行>n无需担心重新启动>n .incrpa些 .incrpan>&inherit;"t><理域对象<它具有一ull方法e如>he接口定义所示>nahopjjp= 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b< nt>public i erface>ospan> {ns:b span nt>(span nt>i gridSize) ;<-align:beans ns:b<容易 ><-align:bgn:bns:b<容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f nn与输入参数以形式ncrpa些 .incrpan>&inherit;"t><理域对象<关联 ><-align:beans ns:b< nt>gONED任l-aliExecutionC ext <-align:beans ns:b< nt>gONED任l-aliExecutionC ext ne行号e或输入文CR置 .incrpa些>n远程gONED任l-ali#{…​}he文输入 nt>g>n步骤作用域中CR后期绑定>n>ne如节所述 .incrpa些 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f nn在aCR步骤执行中必须是唯的>nen是phe前缀+后缀CR命名约定>ne其前缀是正e执行CR步骤的名称>n其本身e是唯的n>ne而后缀只是ll计数器 .incrpa些 .incrpan>&inherit;"t><理域对象<有一ull<-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f ne则e重新启动时仅查询名称 .incrpa些>&inherit;"t><理域对象<所提供的名称ncrpa些ONED任l-aliPa;titionNameProvider gONED任l-aliPa;titioner <-align:bgn:b容易 ><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<将输入数据绑定到步骤hopjjp= h4易 ><-align:beansns:b< nt><-align:beansns:bns:b h5的/f ne并在运行时从中绑定其输入参数>nellt><-align:beansns:bns:b< nt>g>gONED任l-aliExecutionC ext n有关Jo系轻- } h5的/f n .incrpa些 .incrpan>&inherit;"t><理域对象<例如>ne如果gONED任l-aliExecutionC ext ne则每次调phe均指向不同的文>n或目录>n>ne则nahopjjp= 得知titlfon t><-align:bgn:bns:b<-align:beansns:bns:bgONED任l-aliPa;titioner &inherit;"t><理域对象<提供的示例执行名称到执行上>he文的上>he文hopjjp= captionallt><-align:beansns:bns:b&iwidth: 50%;ballt><-align:beansns:bns:bns:b&iwidth: 50%;ballt><-align:beansns:bns:b <-align:beansns:bns:bns:b<-left v><-topgpnt> h5的/f n键>nhopjjp= emM<-align:beansns:bns:bns:b<-left v><-topgpnt> h5的/f n值>nhopjjp= emM<-align:beansns:bns:b<-align:beansns:bns:b<-align:beansns:bns:bns:b<-left v><-topgpnt> h5的/f na分区0hopjjp= 得<-align:beansns:bns:bns:b<-left v><-topgpnt> h5的/f <-align:beansns:bns:b<-align:beansns:bns:b<-align:beansns:bns:bns:b<-left v><-topgpnt> h5的/f na a;tition1hopjjp= 得<-align:beansns:bns:bns:b<-left v><-topgpnt> h5的/f <-align:beansns:bns:b<-align:beansns:bns:b<-align:beansns:bns:bns:b<-left v><-topgpnt> h5的/f na a;tition2hopjjp= 得<-align:beansns:bns:bns:b<-left v><-topgpnt> h5的/f <-align:beansns:bns:b<-align:beansns:bns:b<-align:beansns:b< nt><-align:beansns:bns:b h5的/f n可以>phe后期绑定到执行上>he文将文名绑定到步骤e如>he示例所示>nahopjjp= 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b< nt>XML C figuration容易 ><-align:beansns:bns:b< nt> <span nt>beanid=span nt>"itemReader"scope =span nt>"step" ><-aspan nt>nt><=span nt>"org.spo...MultiResourceItemReader">/span> ><span nt> rop yname =span nt>"resources"value =span nt>"#{stepExecutionC ext[fileName]}/*"/>/span>span nt></span nt>bean>/span> <-align:beans <-align:bgn:bns:b<容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b< nt><-align:beansns:bns:b< nt>public MultiResourceItemReader span nt>( @Value(span nt>"#{stepExecutionC ext['fileName']}/*") Resource [] resources) { return span nt>new MultiResourceItemReaderBuilder<Sto>()"itemReader")<-align:beans <-align:bgn:bns:b<容易 ><-align:bgn:b<容易 ><-align:b<容易 ><-ali<容易 ><<容易 ><< nt><-aliJoo hunk } : e e>Jo系轻- } h5的/f gONED任/h2allt><-ali< nt><-align:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<重复模板 nt>gONED任/h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f n可以>为简单CR优化或>为工作b一部分 .incrpa些 .incrpan>&inherit;"t><理域对象ne并提供相当迭代器框架bCR内容>neSpo Batch具有 nt>gONED任l-aliRepeatOp ations<-align:beans nt>gONED任l-aliRepeatOp ationshe定义>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>public i erface>ospan> { span nt>(RepeatCallback callback) span nt>throws RepeatException;<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne如>he定义所示>ne该接口使您可以插入些要重复b业务逻辑>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>public i erface>ospan> { span nt>(RepeatC ext c ext) span nt>throws Exception;<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne直到实现确定迭代应结束h止 .incrpa些>h nt>gONED任l-aliRepeatStatus.CONTINUABLEgONED任l-aliRepeatStatus.FINISHED <-align:beansns:bean;枚举传递信息CR重复操作是否有任何更多CR工作要做调phe者 .incrpa些>ne的实现 nt>gONED任l-aliRepeatOp ations<-align:beansns:bean;应检查&inherit;"t><理域对象<何希望通p调phe者没有要做CR工作CR回调都可以返回ncrpa些ONED任l-aliRepeatStatus.FINISHED <-align:bgn:b nt><-align:beansns:b h5的/f gONED任l-aliRepeatOp ationsne如>he示例所示>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>new RepeatTemplate();new SimpleCompletionPolicy(span nt>));new RepeatCallback() {public RepeatStatus span nt>(RepeatC ext c ext) {ns:bns:b ><-a:breturn RepeatStatus.CONTINUABLE;<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f n我们返回ncrpa些ONED任l-aliRepeatStatus.CONTINUABLEne以表明还有更多工作要做 .incrpa些>ne以向调phe者发出信号e表明您没有其他工作要做 .incrpa些>ne其他有效地是无限循环>ne并将完成决策委派给外部策略>ne如例所示 .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<-align:beansns:b< nt><-align:beansns:bns:b h5的/f he文 .incrpa些>ne如有必要e可以将其phe属性包e以在迭代过程中存储瞬态数据 .incrpa些><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f ne则a nt>gONED任l-aliRepeatC ext he文 .incrpa些>he文有时对于存储需要e调phe之间共享的数据很有he nt>gONED任l-aliite ate&inherit;"t><理域对象<例如>ne如果您要计算迭代中事CR发生次数并在后续调phe中记住该事>ne就属这种情况 .incrpa些 得知titlfon t><-align:bgn:b容易 ><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<重复b态t/ nt>g h4易 ><-align:beansns:b< nt><-align:beansns:bns:b&inherit;"t><理域对象<它有两ll可能CR< nt>gONED任l-aliRepeatStatusne如表所示>nahopjjp= 得知titlfon t><-align:bgn:bns:b<-align:beansns:bns:b<-align:beansns:bns:b&iwidth: 50%;ballt><-align:beansns:bns:bns:b&iwidth: 50%;ballt><-align:beansns:bns:b <-align:beansns:bns:bns:b<-left v><-topgpnt> h5的/f <-align:beansns:bns:bns:b<-left v><-topgpnt> h5的/f <-align:beansns:bns:b<-align:beansns:bns:b<-align:beansns:bns:bns:b<-left v><-topgpnt> h5的/f gONED任<-align:beansns:bns:bns:b<-left v><-topgpnt> h5的/f <-align:beansns:bns:b<-align:beansns:bns:b<-align:beansns:bns:bns:b<-left v><-topgpnt> h5的/f gONED任<-align:beansns:bns:bns:b<-left v><-topgpnt> h5的/f <-align:beansns:bns:b<-align:beansns:bns:b<-align:beansns:b< nt><-align:beansns:bns:bphe中CR< nt>gONED任l-aliand() <-align:beansns:bns:b< nt>gONED任l-aliRepeatStatusne如果一b态>h nt>gONED任l-aliFINISHED ne则结果为 ><-align:beans ns:b< nt>gONED任l-aliFINISHED <-align:bgn:b<容易 ><-align:b<容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<完成政策ncrpa些 h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f gONED任l-aliRepeatTemplate neg .incrpan>&inherit;"t><理域对象<循环CR终止ncrpa些>nea nt>gONED任l-aliCompletionPolicy<-align:beans nt>gONED任l-aliRepeatTemplate <-align:beans nt>gONED任l-aliRepeatC ext ne并把它递给negONED任l-aliCompletionPolicyn将存储e ><-align:beans nt>gONED任l-aliRepeatC ext n .incrpa些 .incrpan>&inherit;"t><理域对象<然后>n它询问策略迭代是否完成 .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansns:b h5的/f gONED任l-aliCompletionPolicy<-align:beans nt>gONED任l-aliSimpleCompletionPolicy nllt><-align:beansns:bncrpa些ONED任l-aliRepeatStatus.FINISHED n .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansns:b h5的/f &inherit;"t><理域对象<例如>neulull阻止批处理作在联机系统正e住phe时执行CR批处理窗口将需要自定义策略 .incrpa些 得知titlfon t><-align:b<容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<异常处理ncrpa些 h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne则<-align:bgn:b nt><-align:beansns:b h5的/f he清单显示了ncrpa些 l-aliExceptionHandler nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>public i erface>ospan> {void span nt>(RepeatC ext c ext, Throwabllthrowabll) ><-a:bthrows Throwabll;<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne并在达到限制时失败 .incrpa些>neSpo Batch提供了 ><-align:beans nt>gONED任l-aliSimpleLimitExceptionHandler <-align:beansns:bncrpa些ONED任l-aliRethrowOnThresholdExceptionHandler gONED任l-aliSimpleLimitExceptionHandler ne应与当前异常进行比较bCR异常类型 .incrpa些>&inherit;"t><理域对象<给定类型bCR异常将被忽略>ne直到达到限制>ne然后将它们重新抛出 .incrpa些><-align:bgn:b nt><-align:beansns:b h5的/f ne所以限制仅占当前ne该限制在嵌套迭代>n例如>ne步骤中CR一b块>n中跨R弟上>he文保持 .incrpa些 得知titlfon t><-align:b<容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<听众hopjjp= h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f neSpo Batch提供了 ><-align:beans nt>gONED任l-aliRepeatLjn energONED任l-aliRepeatTemplate <-align:beans ns:b的实现>ne并给他们以回调gONED任l-aliRepeatStatus<-align:beans ns:b迭代过程中>n如有>n .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansns:b h5的/f gONED任l-aliRepeatLjn enerhe定义>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>public i erface>ospan> {ns:bvoid span nt>(RepeatCo ext c ext) ;ns:bvoid span nt>(RepeatC ext c ext, RepeatStatus;ns:bvoid span nt>(RepeatC ext c ext) ;ns:bvoid span nt>(RepeatC ext c ext, Throwablle) ;ns:bvoid span nt>(RepeatCo ext c ext) ;<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f gONED任l-aliopeneo (job, ne>nellt><-align:beansns:bncrpa些 eo aftergONED任l-alionError<-align:bgn:b nt><-align:beansns:b h5的/f ne当侦听器不止ll时>ne它们在列表中>n因此有一ull顺序 .incrpa些>he>nen同时ncrpa些 eo afternellt><-align:beansns:bncrpa些 eo onErrorgONED任l-aliclose<-align:b<容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<并行处理ncrpa些 h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f gONED任l-aliRepeatOp ationsneSpo Batch提供llt><-align:beansns:bncrpa些 eo TaskExecutorRepeatTemplate ne住pheSpo ncrpa些 eo TaskExecutor <-align:beans nt>gONED任l-aliRepeatCallbackne它CR作用是在eul线程>n与normal相同 nt>gONED任l-aliRepeatTemplate nhopjjp=><-align:beans nt>g><-align:b<容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<声明式迭代ncrpa些 h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne您知道某些业务处理每次都想重复进行 .incrpa些>n如果它们经常到达>n>ne则比每条消息承担单独交易CR成本要有效 .incrpa些>ne该方法将方法调phe包装在 nt>gONED任l-aliRepeatOp ationsgONED任l-aliRepeatOp ationsI erceptor gONED任l-aliCompletionPolicygONED任l-aliRepeatTemplate <-align:bgn:b nt><-align:beansns:bpnt>The follow example shows dent ative iteration uns:b the Spo AOP namespace to ><-align:beans ns:brepeat a service cl to a method cled l-aliprocessMessage <-align:beans ns:bc figure AOP i erceptors, see the Spo User Guide):得知titlfon t><-align:bgn:b nt><-align:beansns:b nt> <span nt>aop:c fig>/span> ><span nt>aop:poi cutid=span nt>"transa ional" ><-a:bexpression=span nt>"execution(*bc m..*Service.processMessage(..))" ><span nt>aop:advisorpoi cut-a=span nt>"transa ional" ><-a:badvice-a=span nt>"retryAdvice"order=span nt>"-1"/>/span>span nt></span nt>aop:c fig>/span><span nt>beanid=span nt>"retryAdvice"nt><=span nt>"org.spr...RepeatOp ationsI erceptor"/>/span><<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f he示例演示了如pheJava配置重复对称为CR方法进行服务调phe nt>gONED任l-aliprocessMessage n有关如配置AOP拦截器CR更多详细信息>ne请参见Spo用户指南>n>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>public MyService span nt>() {new ProxyFa ory(RepeatOp ations.nt><.getCnt><);new MyService());new JdkRegexpMethodPoi cut();".*processMessage.*");new RepeatOp ationsI erceptor();new DefaultPoi cutAdvisor(poi cut, i erceptor));return service;<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f gONED任l-aliRepeatTemplate g>g>ne侦听器e其他详细信息>ne可以将的实例 ><-align:beans nt>gONED任l-aliRepeatTemplate <-align:bgn:b nt><-align:beansns:b h5的/f ne则拦截器将始终返回ncrpa些ONED任l-aliRepeatStatus.CONTINUABLEn因此>ne如果 nt>gONED任l-aliCompletionPolicyne则 ><-align:beans nt>g><-align:beans nt>g>n .incrpa些 .incrpan>&inherit;"t><理域对象<否则>ne它将返回llt><-align:beansns:bncrpa些ONED任l-aliRepeatStatus.CONTINUABLEne这时它将返回ncrpa些ONED任l-aliRepeatStatus.FINISHED ne目标方法内eCR业务逻辑可以通过返回ncrpa些ONED任l-alinull<-align:beans ns:b或引发由ncrpa些ONED任l-aliExceptionHandler g><-align:beans nt>g>gONED任l-aliRepeatTemplate <-align:b容易 ><-ali容易 ><容易 >< nt><-aliJoo hunk } : e e>Jo系轻- } h5的/f <-ali< nt><-align:b nt><-align:beans h5的/f ne有时可以自动重试失败CR操作e以防后续尝试成功执行 .incrpa些 .incrpan>&inherit;"t><理域对象<容易出现间歇性故障CR错误通常是暂时性bCR .incrpa些>ne由于网络故障或< nt>gONED任l-aliDeadlockLoserDataAccessException&inherit;"t><理域对象<导致对Web服务的远程调phe失败titlfon t>g><容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- }<-align:bgn:b nt> ><-align:beans tabll易 ><-align:beansns:b tbody<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:b< nt><-align:beansns:bns:bns:bns:bns:b h5的/f ne重试功能已Spo Batch撤出 .incrpa些>Jo系轻- } h5的/f h5的/f <-align:bgn:bns:bns:bns:b<-align:beansns:bns:b<-align:beansns:bns:b<-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f neSpo Batch制定了ncrpa些 l-aliRetryOp ations<-align:beans ns:b策略 .incrpa些>he接口定义ncrpa些 l-aliRetryOp ationsnahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>public i erface>ospan> { span nt>(RetryCallback<T, E>bretryCallback)>ospan>throws E; span nt>(RetryCallback<T, E>bretryCallback, Reco/ yCallback<T>breco/ yCallback) ><-a:bthrows E; span nt>(RetryCallback<T, E>bretryCallback, RetryStatebretryState) ><-a:bthrows E, ExhaustedRetryException; span nt>(RetryCallback<T, E>bretryCallback, Reco/ yCallback<T>breco/ yCallback, ><-a:bRetryStatebretryState)bthrows E;<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne可让您插入些要重试CR业务逻辑>ne如>he接口定义所示>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>public i erface>ospan><span nt>,bex ends>ospan>>b<{ span nt>(RetryCo ext c ext) bthrows E;<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne并且如果失败>n抛出ncrpa些ONED任l-aliException n>ne则会重试ncrpa些>nellt><-align:beansns:bncrpa些><-align:beansns:bncrpa些ONED任l-aliRetryOp ations&inherit;"t><理域对象<当所有重试尝试都phe尽并处理重试状态时>ne这些方法将处理各种用例以进行恢复>ne这使客户端e实现可以在调phe之间存储信息>n我们将在本章稍后详细介绍>n .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansns:b h5的/f <-align:beansns:bncrpa些ONED任l-aliRetryOp ations<-align:beansns:bncrpa些ONED任l-aliRetryTemplate &inherit;"t><理域对象<可以如phe>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>new RetryTemplate();new TimeoutRetryPolicy();30000L);new RetryCallback<Foo>() {public Foo span nt>(RetryCo ext c ext) b<{ns:bns:b ><-a:breturn result;<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f n我们进行了Web服务调phe>ne并将结果返回给用户 .incrpa些>ne则将重试它>ne直到达到超时止 .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- }<-align:beansns:b< nt><-align:beansns:bns:b h5的/f gONED任l-aliRetryCallback<-align:beans ns:bbbbb是个 nt>gONED任l-aliRetryC ext &inherit;"t><理域对象<许多回调会忽略上>he文>ne但如有必要>ne可以将其b作属性包e以在迭代过程中存储数据 .incrpa些 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f ne则g>he文 .incrpa些>he文有时对存储需要在调phe之间共享CR数据很有hencrpa些ONED任l-aliexecute<-align:bgn:b容易 ><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- }<-align:beansns:b< nt><-align:beansns:bns:b h5的/f nllt><-align:beansns:bns:bne称为&inherit;"t><理域对象<要住phe此功能>ne客户端将回调一起传递给相同的方法>ne如>he示例所示>nahopjjp= 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b< nt>new RetryCallback<Foo>() { ns:bpublic Foo span nt>(RetryCo ext c ext) b<{ns:bns:b opjjp= ns:b}, opjjp= nsspan nt>new Reco/ yCallback<Foo>() { ns:b span nt>(RetryCo ext c ext) bthrows Exceptionb<{ns:bns:b:b opjjp= ns:b}<-align:beans gn:b容易 ><-align:bgn:bns:b<-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f ne则可以通过恢复回调为客户端提供一些替代处理CR机会 .incrpa些 得知titlfon t><-align:bgn:b容易 ><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<无状态重试ncrpa些 h4allt><-align:beansns:b< nt><-align:beansns:bns:b h5的/f he>ne重试只是个while循环 .incrpa些><-align:beans gn:brpa些ONED任l-aliRetryTemplate ne直到成功或失败 .incrpa些>gONED任l-aliRetryC ext <-align:beans ns:bbbbb包含了些状态e以确定是否要重试或止>ne但这种状态是在栈上>ne也没有必要存储>ne随时随地全球范围内>ne所以我们称这种无状态CR重试 .incrpa些><-align:beans gn:brpa些ONED任l-aliRetryPolicy<-align:beans gn:brpa些ONED任l-aliRetryTemplate n的实现 .incrpa些>n重试回调始终在失败时所处的eul线程执行 .incrpa些 得知titlfon t><-align:bgn:b容易 ><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<有状态重试ncrpa些 h4allt><-align:beansns:b< nt><-align:beansns:bns:b h5的/f he>ne有一u特殊注意事项 .incrpa些>ne所以这不适phe简单CR远程调phe>ne但是有时它确实适phe数据库更新>ne尤其是在住pheHibernate时 .incrpa些>he>ne仅立即重新抛出b为故障CR异常是有意义的>ne这样事务可以回滚并且我们可以开始ll新CR有效事务 .incrpa些 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f he>ne无状态重试是够的>ne因为重新抛出e回滚必然涉及离开llt><-align:beansns:bns:bhe文 .incrpa些>ne我们必须引入种存储策略以将其从堆栈中取出并(至少>n放入堆存储中 .incrpa些>neSpo Batch提供了种称为CR存储策略llt><-align:beansns:bns:bne可以将其注入 ><-align:beans gn:brpa些ONED任l-aliRetryTemplate <-align:beansns:bns:bn住phesimplellt><-align:beansns:bns:bne也可能考虑llt><-align:beansns:bns:bn但是>ne即使在群集环境中>ne这也可能会过分杀伤>n .incrpa些 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f <-align:beans ns:bn通常包含在新CR事务中>n时识别失败CR操作 .incrpa些>neSpo Batch提供了 ><-align:beans ns:b&inherit;"t><理域对象<这与t/ nt>g .incrpan>&inherit;"t><理域对象<接口中ncrpa些><-align:beansns:bns:b<-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f gONED任l-aliRetryStatene<-align:beansns:bns:b<-align:bgn:bns:b< nt> ><-align:beansns:b tabll易 ><-align:beansns:b tbody<-align:beansns:bns:bns:b tdnt><-align:beansns:bns:bns:bns:b int><-align:beansns:bns:bns:b /tdallt><-align:beansns:bns:bns:b tdnt><-align:beansns:bns:bns:bns:b nt><-align:beansns:bns:bns:bns:bns:b pM> h5的/f gONED任l-aliObjn .equals()gONED任l-aliObjn .hashC-al()<-align:beansns:bns:bns:bns:bns:b nt>gONED任l-aliRetryStatene可以住phe消息ID .incrpa些 得知titlfon t><-align:bgn:bns:bns:bns:b tdallt><-align:beansns:bns:bns:b<-align:beansns:bns:bns:b<-align:beans 容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f ne还可以选择以其他方式处理失败CR项目>ne而不是调phellt><-align:beansns:bns:bn现在假定可能会失败>n .incrpa些 .incrpan>&inherit;"t><理域对象<就像在无状态情况>he一样e此选项由提供ncrpa些ONED任l-aliReco/ yCallback ne可以通过将其传递给ncrpa些ONED任l-aliexecute<-align:beansns:bns:b<-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f <-align:beans gn:brpa些ONED任l-aliRetryPolicyne通常可以将有关限制和超时CR问题注入该规则中>n本章稍后将介绍>n .incrpa些 得知titlfon t><-align:bgn:b容易 ><-align:b<容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<重试政策< nt>gONED任h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f gONED任l-aliRetryTemplate n重试或失败ncrpa些ONED任l-aliexecutenallt><-align:beansns:bncrpa些ONED任l-aliRetryPolicy<-align:beansns:bncrpa些ONED任l-aliRetryC ext &inherit;"t><理域对象<在 ><-align:beans rpa些ONED任l-aliRetryTemplate ne并把它传递给ncrpa些ONED任l-aliRetryCallback nrpa些ONED任l-aliRetryTemplate <-align:beans nt>gONED任l-aliRetryC ext n>ne然后询问策略是否可以进行另次尝试 .incrpa些>n例如达到限制或检测到超时>n>ne则该策略还负责处理耗尽状态 .incrpa些>ne这将导致任何封闭CR事务被回滚 .incrpa些>ne在这种情况>he>ne事务可以保持变 .incrpa些 得知titlfon t><-align:bgn:b nt> ><-align:beans tabll易 ><-align:beansns:b tbody<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:b< nt><-align:beansns:bns:bns:bns:bns:b h5的/f ne还是能重试CR .incrpa些>ne则重试它是没有好处的 .incrpa些>ne请勏重试所有异常类型 .incrpa些>ne请尝试仅关注您希望可重试CR那些异常 .incrpa些>ne但是却是浪费的>ne因为如果确定性bCR失败>ne您将花费时间重试事先知道是致命CR事情 .incrpa些 得知titlfon t><-align:bgn:bns:bns:bns:b<-align:beansns:bns:b<-align:beansns:bns:b<-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f <-align:beans nt>gONED任l-aliSimpleRetryPolicy<-align:beansns:bncrpa些ONED任l-aliTimeoutRetryPolicyn在前面的示例中phe>n .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansns:b h5的/f gONED任l-aliSimpleRetryPolicyne由固定的次数 .incrpa些 .incrpan>&inherit;"t><理域对象<它还有一u“致命”异常列表>ne这些列表永远都不应重试>ne并且此列表会覆盖可重试列表>ne以便可以住phe它来更好地控制重试行为>ne如>he示例所示>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>new SimpleRetryPolicy(); span nt> policy.setMaxAttempts(span nt>5); span nt> policy.setRetryabllExceptions(span nt>new Cnt><[] {Exception.nt><}); span nt> policy.setFatalExceptions(span nt>new Cnt><[] {IllegalStateException.nt><}); RetryTemplate template = span nt>new RetryTemplate();new RetryCallback<Foo>() { ns:bpublic Foo span nt>(RetryCo ext c ext) b<{ns:bns:b opjjp= ns:b} opjjp= });<<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne称为llt><-align:beansns:bncrpa些ONED任l-aliExceptionCnt><-align:beans ns:b抽象ncrpa些>ne通过将异常类型映射到其他策略>ne可以在失败前重试多次 .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansns:b h5的/f ne当对解决方案进行众所周知的>ne特定于解决方案的异常分类可重试和可重试时>ne自定义重试策略就很有意义 .incrpa些 得知titlfon t><-align:b容易 ><-align:b nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<退避政策< nt>gONED任h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne通常需要稍等一u再重试>ne因为通常故障是由某些问题引起的>ne只有通过等待才能解决 .incrpa些><-align:beans nt>gONED任l-aliRetryCallback ne则 ><-align:beans rpa些ONED任l-aliRetryTemplate <-align:beans rpa些ONED任l-aliBackoffPolicy<-align:bgn:b nt><-align:beansns:b h5的/f he代码显示了该接口CR接口定义ncrpa些 l-aliBackOffPolicynahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>public i erface>ospan>b<{ span nt>(RetryCo ext c ext) ;void>ospan> span nt>(BackOffCo ext backOffCo ext) ><-a:bthrows BackOffI erruptedException ;<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f gONED任l-aliObjn .wait()ne以避免两次重试进入锁定步骤而都失败>n这是以太网中学到CR一课>n .incrpa些 .incrpan>&inherit;"t><理域对象<此>neSpo Batch提供了llt><-align:beansns:bncrpa些ONED任l-aliExponentialBackoffPolicy<-align:b<容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<听众< nt>gONED任h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne能够接收更多的回调>ne以解决许多不同的重试中CR交叉问题 .incrpa些 .incrpan>&inherit;"t><理域对象<此>neSpo Batch提供了rpa些ONED任l-aliRetryLjn ener<-align:beans ns:b接口 .incrpa些>gONED任l-aliRetryTemplate ne并给们以回调 nt>gONED任l-aliRetryC ext <-align:beansns:bncrpa些ONED任l-aliThrowabll<-align:bgn:b nt><-align:beansns:b h5的/f he代码显示了CR接口定义ncrpa些 l-aliRetryLjn enernahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>public i erface>ospan>b<{boolean>ospan> span nt>(RetryCo ext c ext, RetryCallback<T, E>bcallback) ;void>ospan> span nt>(RetryCo ext c ext, RetryCallback<T, E>bcallback, Throwabll throwabll) ;void>ospan> span nt>(RetryCo ext c ext, RetryCallback<T, E>bcallback, Throwabll throwabll) ;<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f gONED任l-aliopen<-align:beansns:bncrpa些ONED任l-aliclosehe>ne整ll重试后回调来>ne并 nt>gONED任l-alionErro <-align:beansns:bncrpa些ONED任l-aliclose<-align:beansns:bncrpa些ONED任l-aliThrowabllne则是抛出bCR最后ll错误ncrpa些ONED任l-aliRetryCallback <-align:bgn:b nt><-align:beansns:b h5的/f ne当侦听器不止一u时>ne它们在列表中>ne因此有一u顺序 .incrpa些>he>nencrpa些><-align:beansns:bncrpa些>gONED任l-aliopenne而ncrpa些><-align:b<容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<声明式重试ncrpa些 h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne您知道某些业务处理每次发生时都想重试 .incrpa些>ne该拦截器将方法调phe包装在 nt>gONED任l-aliRetryOp ationsgONED任l-aliRetryOp ationsI ercepto <-align:beansns:bncrpa些ONED任l-aliRetryPolicy<-align:beans rpa些ONED任l-aliRetryTemplate <-align:bgn:b nt><-align:beans <-align:beans ns:bnamespacl tobretry a servicl call toba method calledllt><-align:beansns:bns:b<-align:beansns:bns:bAOP i ercepto s, see the Spo User Guide):得知titlfon t><-align:bgn:b nt><-align:beans < nt><span nt>aop:c fig> ><span nt>aop:poi cut>ospan>id>ospan>=span nt>"transa ional" ><-a:bexpression =span nt>"execution(*bc m..*Servicl.remoteCall(..))" /> ><span nt>aop:advisor>ospan>poi cut-a>ospan>=span nt>"transa ional" ><-a:badvice-a>ospan>=span nt>"retryAdvice">ospan>order=span nt>"-1">ospan>/>span nt></span nt>aop:c fig><span nt>bean>ospan>id>ospan>=span nt>"retryAdvice">ospan> >nt><>ospan>=span nt>"org.spoframework.retry.i ercepto .RetryOp ationsI ercepto ">ospan>/><<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f he示例显示了ll声明式重试>ne该重试性住phejava配置重试对名为CR方法CR服务调phe ><-align:beans rpa些ONED任l-aliremoteCall n有关如配置AOP拦截器CR更多详细信息>ne请参见Spo用户指南>n>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>public MyServicl span nt>() b<{new ProxyFa ory(RepeatOp ations.nt><.getCnt><);new MyServicl());new JdkRegexpMethodPoi cut();".*remoteCall.*">ospan>);new RetryOp ationsI ercepto ();new DefaultPoi cutAdvisor(poi cut, i ercepto ));return>ospan><-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f gONED任l-aliRetryTemplate g><-align:beansns:bncrpa些>ne可以将CR实例 ><-align:beans rpa些ONED任l-aliRetryTemplate <-align:b<容易 ><-ali<容易 ><<容易 ><< nt><-aliJoo hunk } : e e>Jo系轻- } h5的/f <-ali< nt><-align:b nt><-align:beans h5的/f ne因此在此不再赘述 .incrpa些 .incrpan>&inherit;"t><理域对象<但是>ne重要CR是要考虑如“端对端”测试批处理作>ne这是本章要介绍CR内容 .incrpa些><容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<创建单元测试类ncrpa些 h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne框架必须加载作CRrpa些ONED任l-aliApplicationC ext &inherit;"t><理域对象nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b<-align:beansns:bns:b<-align:beansns:bns:bns:b<)na指示该类应pheSpo的JUnit工具hopjjp= 得知titlfon t><-align:beansns:bns:b<-align:beansns:bns:bns:bna指示配置资源rpa些ONED任l-aliApplicationC ext <-align:beansns:b<-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne还可以ncrpa些 .incrpan>&inherit;"t><理域对象&inherit;"t><理域对象<注解ncrpa些>he文中ncrpa些>n例如rpa些ONED任l-aliJobLaunk erTen Utils<-align:bgn:b nt><-align:beansns:b h5的/f he示例显示了正在住pheCR注释>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt> h5的/f <-align:bgn:bns:b< nt>public nt><>ospan>b<{ ... }<<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beans < nt><-align:bgn:bns:b< nt>"/simple-job-raunk er-c ext.xmlD,llt><-align:beansns:bns:bns:bgn:bns:b"/jobs/skipSampleJob.xmlD }) span nt>public nt><>ospan>b<{ ... }<<-align:beans 容易 ><-align:beans容易 ><-align:b<容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<批处理作CR端到端测试ncrpa些 h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne以设置测试条件>ne执行作并验证最终结果 .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansns:b h5的/f he示例中>ne批处理作数据库读取并写入平面文件 .incrpa些>&inherit;"t><理域对象<它将清除CUSTOMER表>ne然后插入10条新记录 .incrpa些>ne测试将rpa些ONED任l-aliJob<-align:beans rpa些ONED任l-aliraunk Job()&inherit;"t><理域对象<启encrpa些 .incrpan>&inherit;"t><理域对象< .incrpa些><-align:beansns:bncrpa些ONED任l-aliraunk Job()<-align:beansns:bncrpa些 .incrpan>&inherit;"t><理域对象< .incrpa些><-align:beansns:bncrpa些ONED任l-aliraunk Job(JobPa;ometer<)&inherit;"t><理域对象<该llt><-align:beansns:bncrpa些ONED任l-aliraunk Job()<-align:beansns:bncrpa些ONED任l-aliJobExecutionne这对于声明有关rpa些ONED任l-aliJob&inherit;"t><理域对象< .incrpa些>he情况>he>ne测试将验证rpa些ONED任l-aliJobnahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beans < nt><-align:bgn:bns:b< nt>"/simple-job-raunk er-c ext.xmlD,llt><-align:beansns:bns:bns:bgn:bns:b"/jobs/skipSampleJob.xmlD }) span nt>public nt><>ospan>b<{ospan> ns:bprivate JobLaunk erTen Utils jobLaunk erTen Utils;private SimpleJdbcTemplate simpleJdbcTemplate;ospan> ns:bpublic span nt>void>ospan> span nt>(DataSourcl dataSourcl) b<{ns:bns:bthis .simpleJdbcTemplate = span nt>new SimpleJdbcTemplate(dataSourcl); ns:bpublic span nt>void>ospan> span nt>() bthrows Exceptionb<{"delete from CUSTOMER">ospan>);ns:bns:bfor>ospan><(span nt>int>ospan>1;10;"ins i o CUSTOMER values (?, 0, ?, 100000)","custome ">ospan> + i);"COMPLETED", jobExecution.getExitStatus().getExitC-al());<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b< nt> h5的/f <-align:bgn:bns:b< nt>public nt><>ospan>b<{ospan> ns:bprivate JobLaunk erTen Utils jobLaunk erTen Utils;private SimpleJdbcTemplate simpleJdbcTemplate;ospan> ns:bpublic span nt>void>ospan> span nt>(DataSourcl dataSourcl) b<{ns:bns:bthis .simpleJdbcTemplate = span nt>new SimpleJdbcTemplate(dataSourcl); ns:bpublic span nt>void>ospan> span nt>() bthrows Exceptionb<{"delete from CUSTOMER">ospan>);ns:bns:bfor>ospan><(span nt>int>ospan>1;10;"ins i o CUSTOMER values (?, 0, ?, 100000)","custome ">ospan> + i);"COMPLETED", jobExecution.getExitStatus().getExitC-al());<-align:beans 容易 ><-align:beans容易 ><-align:b<容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<测试单u步骤ncrpa些 h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne端到端测试方法中CR测试用例可能变得难以管理 .incrpa些>he>nephe测试用例自行测试各u步骤可能会更有phe .incrpa些><-align:beansns:bncrpa些ONED任l-aliJobLaunk erTen Utils<-align:beansns:bncrpa些ONED任l-aliraunk Step ne这需要一u步骤名称和运行不仅仅是特定CRncrpa些ONED任l-aliStep ne从e测试仅针对该步骤设置数据并直接验证其结果 .incrpa些>he面的示例演示如phe该llt><-align:beansns:bncrpa些ONED任l-aliraunk Step nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt><-align:beansns:bns:b"loadFileStep">ospan>);<<-align:beans 容易 ><-align:beans容易 ><-align:b<容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<测试步骤范围的组件 nt>gONED任h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne在运行时为eCR步骤配置的组件会phe步骤作phe域e后期绑定>ne以步骤或作执行中注入上>he文 .incrpa些>ne除非e有一种将上>he文设置好像它们在一步执行中那样CR方法 .incrpa些>nllt><-align:beansns:bncrpa些ONED任l-aliStepScopeTen ExecutionLjn ener<-align:beansns:bncrpa些ONED任l-aliStepScopeTen Utils<-align:bgn:b nt><-align:beansns:b h5的/f he文,如>he示例所示>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>public nt><>ospan>b<{<>ospan> ns:bospan> ns:bospan> ns:bprivate ItemReader<Str>breader;public StepExecution span nt> span nt>() b<{"input.data", span nt>"foo,bar,spam">ospan>);ns:bns:breturn>ospan> ns:bpublic span nt>void>ospan> span nt>() b<{ns:bns:b<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne该框架处理来自配置的应phe程序上>he文bCR赖项注入以注入阅读e .incrpa些><-align:beansns:bncrpa些ONED任l-aliStepScopeTen ExecutionLjn ener<-align:beansns:bncrpa些ONED任l-aliStepExecutionne并phe该方法作测试方法CR上>he文,就好像该执行ncrpa些ONED任l-aliStep &inherit;"t><理域对象< .incrpa些><-align:beansns:bncrpa些ONED任l-aliStepExecutionn .incrpa些>ne则nahopjjp= l-aliStepExecution&inherit;"t><理域对象< .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansns:b h5的/f nencrpa些>ne则ncrpa些ONED任l-aliStepScopeTen ExecutionLjn ener<-align:beansns:bncrpa些ONED任l-aliJobScopeTen ExecutionLjn ener&inherit;"t><理域对象< .incrpa些>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>public nt><>ospan>b<{<>ospan> ns:bospan> ns:bospan> ns:bprivate ItemReader<Str>breader;public StepExecution span nt> span nt>() b<{"input.data", span nt>"foo,bar,spam">ospan>);ns:bns:breturn>ospan> ns:bpublic span nt>void>ospan> span nt>() b<{ns:bns:b<-alignon t><-align:bgn:b容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne则侦听器方法很方便 .incrpa些>ne您可以住phe ><-align:beans rpa些ONED任l-aliStepScopeTen Utilshe示例计算了一示例中显示CR阅读e中可phe项目CR数量>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>int>ospan>new Callable<I eger>() {ns:bnspublic I eger span nt>() bthrows Exceptionb<{int>ospan>0;while (reader.read() != span nt>null ) {return>ospan><-align:beans 容易 ><-align:beans容易 ><-align:b<容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<验证输出文件 nt>gONED任h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne很容易查询数据库以验证输出是否符合预期 .incrpa些 .incrpan>&inherit;"t><理域对象<但是>ne如果批处理作写入文件>ne则验证输出同样重要 .incrpa些>nencrpa些ONED任l-aliAss File <-align:beans rpa些ONED任l-aliass FileEquals <-align:beans rpa些ONED任l-aliFile n或两u ><-align:beans rpa些ONED任l-aliResourcln>ne并逐行断言两u文件具有p同CR内容 .incrpa些>ne可以创建一u具有预期输出CR文件>ne并将其实际结果进行比较,如>he示例所示>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>private span nt>statc span nt>final Sto EXPECTED_FILE = span nt>"src/main/resourcls/data/input.txt">ospan>; span nt>private span nt>statc span nt>final Sto OUTPUT_FILE = span nt>"target/ten -outputs/output.txt">ospan>;new FileSystemResourcl(EXPECTED_FILE),llt><-align:beansns:bns:bns:bspan nt>new FileSystemResourcl(OUTPUT_FILE));<<-align:beans 容易 ><-align:beans容易 ><-align:b<容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<模拟域对象 nt>gONED任h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f he代码片段所示>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>public nt><>ospan> span nt>ex end<>ospan>b<{public ExitStatus span nt>(StepExecution stepExecution) b<{ns:bns:bif (stepExecution.getReadCount() == span nt>0) {ns:bns:bns:breturn>ospan>return>ospan>null ;<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne并检查hopjjp= l-aliStepExecution<-align:beans rpa些>ne从e表示未e成何工作 .incrpa些>ne是它phe于说明在尝试对实p需要Spo Batch域对象CR接口CR类进行单元测试时可能遇到CR问题CR类型 .incrpa些>ne针对侦听器考虑>he单元测试>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>private NoWorkFoundStepExecutionLjn ener ten ed = span nt>new NoWorkFoundStepExecutionLjn ener(); public span nt>void>ospan> span nt>() b<{new StepExecution(span nt>"NoProclsns:bStep">ospan>,llt><-align:beansspan nt>new JobExecution(span nt>new JobInstunke(span nt>1L, span nt>new JobPa;ometer<(),llt><-align:beansns:bns:bns:bbeansspan nt>"NoProclsns:bJob">ospan>)));0);<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne因此hopjjp= l-aliStepExecution<-align:beans rpa些ONED任l-aliJobExecution<-align:beans rpa些ONED任l-aliJobInstunke<-align:beansns:bncrpa些ONED任l-aliJobPa;ometer<<-align:beansns:bncrpa些ONED任l-aliStepExecutionne确实会创建phe于单元测试CR存根对象变得冗长 .incrpa些>neSpo Batch测试模块包括一uphe于创建域对象CR工厂>nahopjjp= eo MetaDataInstunkeFa oryne可以将单元测试更新为更简洁,如>he示例所示>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>private NoWorkFoundStepExecutionLjn ener ten ed = span nt>new NoWorkFoundStepExecutionLjn ener(); public span nt>void>ospan> span nt>() b<{0);<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f <-align:beansns:bncrpa些ONED任l-aliStepExecutiongONED任aataerhttps://docs.spo.io/spo-batch/apidocs/org/spof;omework/batch/ten /MetaDataInstunkeFa ory.; n;"nt>Jo系轻- } h5的/f <-align:beans rpa些><-align:b容易 ><-ali容易 ><容易 >< nt><-aliJoo hunk } : e e>Jo系轻- } h5的/f gONED任h2allt><-ali< nt><-align:b nt><-align:beans h5的/f nencrpa些ONED任l-aliItemReader&inherit;"t><理域对象<但是>ne在大多数情况>he>ne必须编写自定义码 .incrpa些>&inherit;"t><理域对象<>ne对titlfon t>ne对ncrpa些ONED任l-aliItemWh-fernee各种监听器接口 .incrpa些>ne但是通常情况>he>ne在处理e编写过程中存在一u自定义问题>ne需要开发人员实pncrpa些ONED任l-aliItemWh-fer<容易 ><-alins:b< nt><-align:beans h5的/f ne我们提供了些自定义务逻辑中常见模式的示例 .incrpa些>ne如果合适>nencrpa些ONED任l-aliItemReader<容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<记录项目处理e故障 nt>gONED任h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne可能需要登录到特殊通道或将记录插入数据库中 .incrpa些>n步骤工厂bean创建)可以让用户实p这个用例的简单ncrpa些ONED任l-aliItemReadLjn enerhe代码段说明了个侦听器>ne该侦听器记录了读取e写入失败>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>public nt><>ospan> span nt>ex end<>ospan>b<{private span nt>statc Log logger = LogFa ory.getLog(span nt>"item.error");public span nt>void>ospan> span nt>(Exceptionbex) b<{"Encountered error onbread", l);public span nt>void>ospan> span nt>(Exceptionbex, Ljn <? ex end< Objn >bitems) b<{"Encountered error onbwh-fe", lx);<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne必须向其注册一u步骤,如>he示例所示>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt><-align:bgn:bns:b< nt><span nt>id>ospan>=span nt>"simpleStep">ospan>>opjjp= <span nt>> ns:b<span nt>> ns:bns:b<span nt>nt><>ospan>=span nt>"org.example...ItemFailureLoggerLjn ener">ospan>/> ns:b</span nt>> </span nt>> </span nt>><<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b< nt><-align:bgn:bns:b< nt>public Step span nt>() b<{ span nt>return>ospan>this .stepBuilderFa ory.get(span nt>"simpleStep">ospan>)opjjp= .ljn ener(span nt>new ItemFailureLoggerLjn ener())<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b<-align:beansns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bbean<理域对象<考虑向该方法添加声明性事务>n有关详细信息>ne请参见《 Spo Core参考指南》>n>ne并将其播属性CR值设置ncrpa些ONED任l-aliREQUIRES_NEW<-align:beansns:bns:bns:b<-align:beansns:bns:btrallt><-align:beansns:bns:btbody><-align:beans容易 ><-align:b<容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<由于务原因手动停止作 nt>gONED任h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne但这实际上是操作员而非应phe程序程序员住pheCR .incrpa些>ne从务逻辑中停止作执行更方便或更有意义 .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansns:b h5的/f n既不会无限期重试>ne不会跳过>n .incrpa些>ne可以住phe自定义异常类型,如>he示例所示>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>public nt><>ospan><span nt>>bimplement<>ospan><span nt>, span nt>>b<{ ns:bpublic T span nt> span nt>(Tbitem) bthrows Exceptionb<{ns:bns:bif (isPoisonPill(item)) {ns:bns:bns:bthrow>ospan>new PoisonPillException(span nt>"Poison pill detn ed: ">ospan> +bitem);return>ospan><-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f <-align:beansns:bncrpa些ONED任l-aliItemReaderne如图>he示例>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>public nt><>ospan>implement<>ospan><span nt>>b<{private ItemReader<T>bdelegate;public span nt>void>ospan> span nt>(ItemReader<T>bdelegate) b<{ ...b}public T span nt> span nt>() bthrows Exceptionb<{if (isEndItem(item)) {ns:bns:bns:breturn>ospan>null ;b opjjp= ns:bns:b}return>ospan><-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f he事实>na该hopjjp= l-aliCompletionPolicy&inherit;"t><理域对象<要处理的物料为时发出e整批次CR信号ncrpa些ONED任l-alinull ne并将其ncrpa些ONED任l-aliStephe示例所示>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt><-align:bgn:bns:b< nt><span nt>id>ospan>=span nt>"simpleStep">ospan>> ns:b<span nt>> ns:bns:b<span nt>reader=span nt>"reader" wh-fer=span nt>"wh-fer" commit-interval =span nt>"10" ns:bns:bs:bns:bchunk-completion-policy=span nt>"completionPolicy">ospan>/> ns:b</span nt>> </span nt>><span nt>id>ospan>=span nt>"completionPolicy">ospan>nt><>ospan>=span nt>"org.example...SpecialCompletionPolicy">ospan>/><<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b< nt><-align:bgn:bns:b< nt>public Step span nt>() b<{ span nt>return>ospan>this .stepBuilderFa ory.get(span nt>"simpleStep">ospan>)new SpecialCompletionPolicy())<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne该标记ncrpa些ONED任l-aliStepExecution<-align:beansns:bns:b项目处理之间CR框架中hopjjp=>ne我们需要访问current ncrpa些ONED任l-aliStepExecutionne这可以通过实pa ncrpa些ONED任l-aliStepLjn enerhe示例显示了设置标志的侦听器>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>public nt><>ospan>ex end<>ospan>bimplement<>ospan>b<{private StepExecution stepExecution;public span nt>void>ospan> span nt>(StepExecution stepExecution) b<{ns:bns:bthis .stepExecution = stepExecution;public span nt>void>ospan> span nt>(Objn bitem) b<{ns:bns:bif (isPoisonPill(item)) {<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne默认行为是抛出CR步骤llt><-align:beansns:bncrpa些ONED任l-aliJobInterruptedException<-align:beansns:bncrpa些ONED任l-aliStepInterruptionPolicy&inherit;"t><理域对象<但是>ne唯一的选择是引发或不引发异常>ne因此>ne这始终是工作的异常结束 .incrpa些 得知titlfon t><-align:b容易 ><-align:b nt><-align:beanse>Joo hunk } : e e>Jo系轻- }aM> h5的/f g .incrpan>&inherit;"t><理域对象<添加页脚记录 nt>gONED任h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne在写入平面文件时>ne在e成所有处理之后>ne必须在文件末尾附加“页脚”记录 .incrpa些>g .incrpan>&inherit;"t><理域对象<来实pllt><-align:beansns:bncrpa些>&inherit;"t><理域对象<-align:beansns:bns:b(e它的对应pCRncrpa些ONED任l-aliFla FileHeaderCallback<-align:beansns:bncrpa些ONED任l-aliFla FileItemWh-ferne并且可以被添加到如在下面的例子中示出CR条目写入器>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt><-align:bgn:bns:b< nt><span nt>id>ospan>=span nt>"itemWh-fer">ospan>nt><>ospan>=span nt>"org.spr...Fla FileItemWh-fer">ospan>> ns:b<span nt>ospan>name=span nt>"resourcl">ospan>a>ospan>=span nt>"outputResourcl">ospan> ns:b<span nt>ospan>name=span nt>"lineAggregator">ospan>a>ospan>=span nt>"lineAggregator">ospan>/> ns:b<span nt>ospan>name=span nt>"headerCallback">ospan>a>ospan>=span nt>"headerCallback">ospan> ns:b<span nt>ospan>name=span nt>"footerCallback">ospan>a>ospan>=span nt>"footerCallback">ospan> </span nt>><<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b< nt><-align:bgn:bns:b< nt>public Fla FileItemWh-fer<Str>b span nt>(Resourcl outputResourcl) b<{ span nt>return>ospan>new Fla FileItemWh-ferBuilder<Str>()"itemWh-fer">ospan>)<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f he接口定义所示>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>public interface span nt>b<{void>ospan> span nt>(Wh-ferbwh-fer) bthrows IOException;<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:be>Joo hunk } : e e>Jo系轻- }aM> h5的/f g .incrpan>&inherit;"t><理域对象<编写摘要页脚 nt>gONED任h4allt><-align:beansns:b< nt><-align:beansns:bns:b h5的/f ne并将此信息附加到文件末尾 .incrpa些><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f ne如果批处理作正在将ncrpa些ONED任l-aliTradeg>g>ne并且要求将所有记录中CR总数ncrpa些ONED任l-aliTrade<ne那么ncrpa些ONED任l-aliItemWh-ferhencrpa些>nahopjjp= 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b< nt>public nt><>ospan>implement<>ospan><span nt>>,llt><-align:beansns:bns:bns:bbeanns:bns:bb<{private ItemWh-fer<Trade>bdelegate;private BigDecimal totalAmount = BigDecimal.ZERO;public span nt>void>ospan> span nt>(Ljn <? ex end< Trade>bitems) bthrows Exceptionb<{for (Trade trade :bitems) { opjjp= ns:bns:btotalAmount = totalAmount.add(chunkTotal);public span nt>void>ospan> span nt>(Wh-ferbwh-fer) bthrows IOExceptionb<{"Total Amount Proclsned: ">ospan> +btotalAmount);public span nt>void>ospan> span nt>(ItemWh-ferbdelegate) b<{...}<-align:beans ns:b<容易 ><-align:bgn:bns:b<容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f nencrpa些>g><-align:beansns:bns:bns:b每uncrpa些ONED任l-aliTradene框架调phe ><-align:beans ns:bne将ncrpa些ONED任l-alitotalAmountne该ne该临时变量<-align:beans ns:bne如果在ncrpa些ONED任l-aliwh-fe <-align:beans ns:bne则将ncrpa些ONED任l-alitotalAmount<-align:beansns:bns:bns:b方法ncrpa些>ne一旦我们证不会引发任何异常>ne就可以更新llt><-align:beansns:bns:b<-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f nencrpa些ONED任l-aliTradeItemWh-fer<-align:beansns:bns:bhe示例显示了如执行此操作>nahopjjp= 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b< nt><-align:bgn:bns:bns:b< nt><span nt>id>ospan>=span nt>"tradeItemWh-fer">ospan>nt><>ospan>=span nt>"..TradeItemWh-fer">ospan>> ns:b<span nt>ospan>name=span nt>"delegate">ospan>a>ospan>=span nt>"fla FileItemWh-fer">ospan> </span nt>><span nt>id>ospan>=span nt>"fla FileItemWh-fer">ospan>nt><>ospan>=span nt>"org.spr...Fla FileItemWh-fer">ospan>> ns:<span nt>ospan>name=span nt>"resourcl">ospan>a>ospan>=span nt>"outputResourcl">ospan> ns:<span nt>ospan>name=span nt>"lineAggregator">ospan>a>ospan>=span nt>"lineAggregator">ospan>/> ns:<span nt>ospan>name=span nt>"footerCallback">ospan>a>ospan>=span nt>"tradeItemWh-fer">ospan> </span nt>><<-align:beans eans容易 ><-align:bgn:bns:b<容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b< nt><-align:bgn:bns:bns:b< nt>public TradeItemWh-fer span nt>() b<{new TradeItemWh-fer();null ));return>ospan> public Fla FileItemWh-fer<Str>b span nt>(Resourcl outputResourcl) b<{ span nt>return>ospan>new Fla FileItemWh-ferBuilder<Str>()"itemWh-fer">ospan>)<-align:beans eans容易 ><-align:bgn:bns:b<容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f <-align:beans ns:bn>ne但是ne在重新启动CR情况>he无法检索到它 .incrpa些>nencrpa些ONED任l-aliItemStream <-align:beans ns:bhe示例所示>nahopjjp= 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b< nt>public span nt>void>ospan> span nt>(ExecutionC ext executionC ext) b<{ns:bspan nt>if (executionC ext.c ainsKey(span nt>"total.amount">ospan>) {"total.amount">ospan>);public span nt>void>ospan> span nt>(ExecutionC ext executionC ext) b<{"total.amount">ospan>,btotalAmount);<-align:beans eans容易 ><-align:bgn:bns:b<容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f <-align:beans ns:bnene从而允许该ne而重新启动是在上一次ncrpa些ONED任l-aliStep<-align:bgn:b容易 ><-align:b容易 ><-align:b nt><-align:beanse>Joo hunk } : e e>Jo系轻- }aM> h5的/f g .incrpan>&inherit;"t><理域对象<基于驱动查询CRItemReader<-align:bgn:b nt><-align:beansns:b h5的/f Jo系轻- } h5的/f Jo系轻- } h5的/f ne讨论了使phe分页的数据库输入 .incrpa些>ne例如DB2>ne都具有极其悲观的锁定策略>ne如果正在读取的表也需要由联机应p程序CR其他e分使phe>ne则可能导致问题 .incrpa些>ne在非常大的数据集上打开游标可能会导致某些供应商的数据库出现问题 .incrpa些>ne许多项目更喜欢使phe“驱动查询”方法来读取数据 .incrpa些>ne而不是遍历需要返回的整个对象,如图所示>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt><-align:beansns:bns:b驾驶查询作ballt><-align:beansns:b<容易 ><-align:bgn:bns:b< nt><f<titleD  (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结图25.驱动查询作hopjjp=      容易 ><-align:bgn:b容易 ><-align:bgn:b nt><f< a;obL<ballt><-align:beansns:b<pM>
  h5的/f  </dalignlassljdg><foftory;/   jd予想t><aunch-f结如您所见>ne上图显示的示例使phe与基于游标的示例相同的“ FOO”表 .incrpa些><foftory;/tica     ory;/tip
<t, 但是>ne不是选择整个e>ne而是在SQL语句选择了ID .incrpa些><foftory;/tica     ory;/tip
<t, 因此>ne不是ncrpa些ONED任l-aliFOO</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结从返回<rpa些><foftory;/   jd予想t><aunch-f结一uncrpa些><foftory;/   jd予想t><aunch-f结对象ncrpa些><foftory;/   jd予想t><aunch-f结>ne而是ncrpa些><foftory;/tica     ory;/tip
<t, 返回了ncrpa些ONED任l-aliread</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结一uncrpa些ONED任l-aliInteger</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结 .incrpa些 .incrpan>&inherit;<理域对象<然后可以住phe该数字查询“细节”,它是ue整pCRncrpa些ONED任l-aliFoonahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt><-align:beansns:bns:b驾驶查询示例ballt><-align:beansns:b<容易 ><-align:bgn:bns:b< nt><f<titleD  (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结图26.驾驶查询示例hopjjp=      容易 ><-align:bgn:b容易 ><-align:bgn:b nt><f< a;obL<ballt><-align:beansns:b<pM>
  h5的/f  </dalignlassljdg><foftory;/   jd予想t><aunch-f结一uncrpa些ONED任l-aliItemProclsnor</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结应p于转化从驱动查询转换成ue整pCR“富”对象获得的密钥 .incrpa些><foftory;/tica     ory;/tip
<t, p有的DAO可以p于根据密钥查询e整pCR对象 .incrpa些      得知titlfon t><Mag容易 ><-align:b容易 ><-align:b nt><f<on 2<-align:beanse>Joo hunk } : e e>Jo系轻- }aM> h5的/f g .incrpan>&inherit;"t><理域对象<多e记录 nt>gONED任h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne但通常一u文件中CR记录可能会跨越具有多种格式CR多e .incrpa些>he文件摘录显示了这种安排的示例>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt> h5的/f ne2>ne2>ne267.34hopjjp= 得re易 ><-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne必须考虑以>he几点>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b<-align:beansns:bns:b<-align:beansns:bns:bns:b h5的/f nencrpa些>g>ne这样才能将其传递给ncrpa些ONED任l-aliItemWh-fer<-align:beansns:bns:b<-align:beansns:bns:bns:b h5的/f <-align:beansns:b<-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne并且由于我们可能不知道有多少e>ne因此ncrpa些ONED任l-aliItemReadernencrpa些ONED任l-aliItemReader<-align:beansns:bhe示例所示>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt><-align:bgn:bns:b< nt><span nt>id>ospan>=span nt>"itemReader">ospan>nt><>ospan>=span nt>"org.spr...MultiLineTradeItemReader">ospan>> ns:b<span nt>ospan>name=span nt>"delegate">ospan>> ns:bns:b<span nt>nt><>ospan>=span nt>"org.sprframework.batch.item.file.Fla FileItemReader">ospan>> ns:bns:bns:b<span nt>ospan>name=span nt>"resourcl">ospan>value=span nt>"data/iosample/input/multiLine.txt">ospan> ns:bns:bns:b<span nt>ospan>name=span nt>"lineMapper">ospan>> ns:bns:bns:bns:b<span nt>nt><>ospan>=span nt>"org.spr...DefaultLineMapper">ospan>> ns:bns:bns:bns:bns:b<span nt>ospan>name=span nt>"lineTokenizer">ospan>a>ospan>=span nt>"orderFileTokenizer">ospan>/> ns:bns:bns:bns:bns:b<span nt>ospan>name=span nt>"fieldSetMapper">ospan>a>ospan>=span nt>"orderFieldSetMapper">ospan>/> ns:bns:bns:bns:b</span nt>> ns:bns:bns:b</span nt>ospan>> ns:bns:b</span nt>> ns:b</span nt>ospan>> </span nt>><<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b< nt><-align:bgn:bns:b< nt>public MultiLineTradeItemReaderb span nt>() b<{new MultiLineTradeItemReader();return>ospan> public Fla FileItemReaderb span nt>() b<{new Fla FileItemReaderBuilder<>()"fla FileItemReader">ospan>)new Cnt>"data/iosample/input/multiLine.txt">ospan>))return>ospan><-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne这对于定长输入尤其重要>nencrpa些ONED任l-aliPatternMatchCompositeLineTokenizernencrpa些><-align:beansns:bJo系轻- } h5的/f &inherit;"t><理域对象<然后,委托阅读器住pheab<-align:beansns:b<-align:beansns:bhe示例所示>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansn :b< nt><-align:bgn:bns:b< nt><span nt>id>ospan>=span nt>"orderFileTokenizer">ospan>nt><>ospan>=span nt>"org.spr...PatternMatchCompositeLineTokenizer">ospan>> ns:b<span nt>ospan>name=span nt>"tokenizers">ospan>> ns:bns:b<span nt>ospan>> ns:bns:bns:b<span nt>ospan>key=span nt>"HEA*">ospan>value-a>ospan>=span nt>"headerRecordTokenizer">ospan> ns:bns:bns:b<span nt>ospan>key=span nt>"FOT*">ospan>value-a>ospan>=span nt>"footerRecordTokenizer">ospan> ns:bns:bns:b<span nt>ospan>key=span nt>"NCU*">ospan>value-a>ospan>=span nt>"customerLineTokenizer">ospan> ns:bns:bns:b<span nt>ospan>key=span nt>"BAD*">ospan>value-a>ospan>=span nt>"billAddressLineTokenizer">ospan> ns:bns:b</span nt>ospan>> ns:b</span nt>ospan>> </span nt>><<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b< nt><-align:bgn:bns:b< nt>public PatternMatchCompositeLineTokenizer span nt>() b<{new PatternMatchCompositeLineTokenizer();new HashMap<>(span nt>4>ospan>);"HEA*">ospan>, headerRecordTokenizer());"FOT*">ospan>, footerRecordTokenizer());"NCU*">ospan>, customerLineTokenizer());"BAD*">ospan>, billAddressLineTokenizer());return>ospan><-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne以便它可以连续地调phencrpa些ONED任l-aliread() ne直到到达末尾 .incrpa些>ne包装器应构建要返回的项目 .incrpa些>he示例所示>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>private Fla FileItemReader<FieldSet>bdelegate;public Trade span nt> span nt>() bthrows Exceptionb<{null ;for (FieldSet line =null ; (line =this .delegate.read()) !=null ;) {0>ospan>); ns:bns:bif (prefix.equals(span nt>"HEA">ospan>)) {new Trade();b opjjp= ns:bns:b} opjjp= ns:bns:bspan nt>else bif (prefix.equals(span nt>"NCU">ospan>)) {"No header was found.">ospan>);1>ospan>));2>ospan>));else bif (prefix.equals(span nt>"BAD">ospan>)) {"No header was found.">ospan>);4>ospan>));6>ospan>));else bif (prefix.equals(span nt>"FOT">ospan>)) { ns:bns:bns:breturn>ospan> opjjp= ns:bns:b} opjjp= ns:b} opjjp= ns:bAss .isNull(t,b"No 'END' was found.">ospan>); eansreturn>ospan>null ;<-align:beans 容易 ><-align:beans容易 ><-align:b容易 ><-align:b nt><-align:beanse>Joo hunk } : e e>Jo系轻- }aM> h5的/f g .incrpan>&inherit;"t><理域对象<执行系统命令ncrpa些ONED任h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne但是有关运e的通phe元数据的优势将丢失 .incrpa些>ne也需要将多步骤作拆分为多个作 .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansns:b h5的/f ne因此Spr Batch提供了一种ncrpa些ONED任l-aliTasklethe示例所示>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansn :b< nt><-align:bgn:bns:b< nt><span nt>nt><>ospan>=span nt>"org.sprframework.batch.core.step.tasklet.SystemCommandTasklet">ospan>> ns:b<span nt>ospan>name=span nt>"command">ospan>value=span nt>"ek } hello">ospan> ns:b ns:b<span nt>ospan>name=span nt>"timeout">ospan>value=span nt>"5000">ospan> </span nt>><<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b< nt><-align:bgn:bns:b< nt>public SystemCommandTasklet span nt>() b<{new SystemCommandTasklet();"ek } hello">ospan>);5000>ospan>);return>ospan><-align:beans 容易 ><-align:beans容易 ><-align:b容易 ><-align:b nt><-align:beanse>Joo hunk } : e e>Jo系轻- }aM> h5的/f g .incrpan>&inherit;"t><理域对象<未找到输入时处理步骤e成ncrpa些ONED任h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne在数据库或文件中找不到要处理的e并不是例外 .incrpa些>ne这可能会引起一u混乱(通常是在文件名错误或出现类似问题时发生) .incrpa些>ne应检查元数据本身>ne以确定发现要处理的框架有多少工作 .incrpa些>ne如果找不到任何输入被认为是例外情况怎么办?ncrpa些>he>ne最好以编程方式检查元数据是否有未处理的项目并导致失败 .incrpa些>ne所以Spr Batch为监听器提供了恰好此功能,如>he类的p定义所示<-align:bgn:b nt><-align:beansns:b< nt>public span nt>nt><>ospan>ex end<>ospan>b<{public ExitStatus span nt>(StepExecution stepExecution) b<{ns:beansif (stepExecution.getReadCount() ==0>ospan>) { ns:bns:bns:breturn>ospan>return>ospan>null ;<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f <-align:beansns:bhe>ne将返回退出代码FAILED>ne表明该操作nencrpa些ONED任l-alinull ne这不会影响的p态<-align:b容易 ><-align:b nt><-align:beanse>Joo hunk } : e e>Jo系轻- }aM> h5的/f g .incrpan>&inherit;"t><理域对象<将数据递到将来pCR步骤ncrpa些ONED任h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f <-align:beansns:bne一u在ne而nencrpa些ONED任l-aliStepne而<-align:bgn:b nt><-align:beansns:b h5的/f ne所有数据必须在<-align:beansns:bns:bne则在ne该数据将丢失 .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>public span nt>nt><>ospan>bimplement<>ospan><span nt>>b<{ns:bspan nt>private StepExecution stepExecution;public span nt>void>ospan> span nt>(Ljn <? ex end< Object>bitems) bthrows Exceptionb<{ ns:bns:bspan nt> opjjp= opjjp= ns:bns:bExecutionC ext stepC ext =this .stepExecution.getExecutionC ext();"someKey">ospan>, someObject); ns:bpublic span nt>void>ospan> span nt>(StepExecution stepExecution) b<{ns:beansthis .stepExecution =<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne必须在<-align:beansns:bns:b<-align:beansns:bns:bnencrpa些ONED任l-aliStephe示例所示>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansn :b< nt><-align:bgn:bns:b< nt><span nt>id>ospan>=span nt>"job1">ospan>> ns:b<span nt>id>ospan>=span nt>"step1">ospan>> ns:bns:b<span nt>> ns:bns:bns:b<span nt>reader=span nt>"reader">ospan>wh-fer=span nt>"savWh-fer">ospan>ommit-i erval=span nt>"10">ospan>/> ns:bns:b</span nt>> ns:bns:b<span nt>> ns:bns:bns:b<span nt>a>ospan>=span nt>"promotionLjn ener">ospan>/> ns:bns:b</span nt>> ns:b</span nt>><span nt>id>ospan>=span nt>"step2">ospan>></span nt>> </span nt>><span nt>id>ospan>=span nt>"promotionLjn ener">ospan>nt><>ospan>=span nt>"org.spr....ExecutionC extPromotionLjn ener">ospan>> ns:b<span nt>ospan>name=span nt>"keys">ospan>> ns:bns:b<span nt>> ns:bns:bns:b<span nt>>someKey</span nt>> ns:bns:b</span nt>> ns:b</span nt>ospan>> </span nt>><<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b< nt><-align:bgn:bns:b< nt>public Job span nt>() b<{ return>ospan><this .jobBuilderFactory.get(span nt>"job1">ospan>) public Step span nt>() b<{ return>ospan><this .stepBuilderFactory.get(span nt>"step1">ospan>)10>ospan>) public ExecutionC extPromotionLjn ener span nt>() b<{new ExecutionC extPromotionLjn ener();new Str[] {span nt>"someKey">ospan> });return>ospan><-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne如>he示例所示>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt>public span nt>nt><>ospan>bimplement<>ospan><span nt>>b<{ns:bspan nt>private Object someObject;public span nt>void>ospan> span nt>(Ljn <? ex end< Object>bitems) bthrows Exceptionb<{ ns:bns:bspan nt> opjjp= ns:b} opjjp= ns:bpublic span nt>void>ospan> span nt>(StepExecution stepExecution) b<{this .someObject ="someKey">ospan>);<-align:beans 容易 ><-align:beans容易 ><-align:b容易 ><-ali容易 ><容易 >< nt><-alie>Joo hunk } : e e>Jo系轻- }aM> h5的/f <-ali< nt><-align:b nt><-align:beans h5的/f ne已完全实p对JSR-352pCR支持 .incrpa些>ne而是要解释JSR-352p定概念如应p于Spr Batch .incrpa些>ne可以通过JCP在这里找到>nahopjjp= aataerhttps://jcp.org/en/jsr/detail?352"nt>Jo系轻- }Jo系轻- }容易 ><-align:b nt><-align:beanse>Joo hunk } : e e>Jo系轻- }aM> h5的/f g .incrpan>&inherit;"t><理域对象<有关Spr Batch和JSR-352pCRu般说明ncrpa些ONED任h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne处理者>ne作家和听众 .incrpa些>ne它们之间pCRu互作phe略有不同 .incrpa些>nencrpa些ONED任l-aliorg.sprframework.batch.core.SkipLjn ener#onSkipInWh-fe(Sbitem, Throwable t) <-align:beansns:bns:bSpr Batch中ncrpa些>na被跳过的项目和导致跳过的异常 .incrpa些>ne第u是ncrpa些ONED任l-aliLjn ne第u是ncrpa些ONED任l-aliExceptionne因此需要p别注意CR是>ne在Spr Batch中有两种执行作的路径a统的Spr Batch作或基于JSR-352pCRu .incrpa些>ne写入器等)将在通过JSR-352pCRJSL配置并通过执行CR工作中工作llt><-align:beansns:bne但它们将根据JSR-352pCR规则运e .incrpa些>ne针对JSR-352接口开发pCR批处理工件将无法在传统的Spr Batch作中住phe .incrpa些 得知titlfon t><-align:b容易 ><-align:b nt><-align:beanse>Joo hunk } : e e>Jo系轻- }aM> h5的/f g .incrpan>&inherit;"t><理域对象<设定ncrpa些ONED任h3易 ><-align:bgn:b nt><-align:beansns:be>Joo hunk } : e e>Jo系轻- }aM> h5的/f g .incrpan>&inherit;"t><理域对象<应p环境ncrpa些ONED任h4allt><-align:beansns:b< nt><-align:beansns:bns:b h5的/f nencrpa些ONED任l-aliJobRepositorynellt><-align:beansns:bns:bg .incrpan>&inherit;"t><理域对象<覆盖此u下文<-align:bgn:bns:b< nt><-align:beansns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:b<-align:beansns:bns:bns:bns:bns:biallt><-align:beansns:bns:bns:bns:b<-align:beansns:bns:bns:bns:b<-align:beansns:bns:bns:bns:bns:b< nt><-align:beansns:bns:bns:bns:bns:bns:b h5的/f ne因此无需在其中配置任何需要额外处理的组件 .incrpa些 得知titlfon t><-align:bgn:bns:bns:bns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:b<-align:beansns:b容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:be>Joo hunk } : e e>Jo系轻- }aM> h5的/f g .incrpan>&inherit;"t><理域对象<启动基于JSR-352pCRuncrpa些ONED任h4allt><-align:beansns:b< nt><-align:beansns:bns:b h5的/f he代码是执行第u批处理作所需pCR全e>nahopjjp= 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b< nt>"myJob">ospan>, span nt>new Prop ies());<<-align:beans eans容易 ><-align:bgn:bns:b<容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f ne但细节在于魔鬼 .incrpa些>he是第次ncrpa些ONED任l-aliBatchRuntime.getJobOperator()g .incrpan>&inherit;"t><理域对象<引导的引导程序nahopjjp= 得知titlfon t><-align:bgn:bns:b<-align:beansns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:btitlfon t><-align:beansns:bns:bns:bpnt>em (job, <-align:beansns:bns:bns:bpnt>em (job, <-align:beansns:bns:bns:bpnt>em (job, <-align:beansns:bns:b<-align:beansns:bns:b<-align:beansns:bns:bns:bpnt>(job, <-align:beansns:bns:bns:bpnt>(job, <-align:beansns:bns:bns:bpnt>(job, he>neHSQLDB被引导 .incrpa些 得<-align:beansns:bns:b<-align:beansns:bns:b<-align:beansns:bns:bns:bpnt>eo transa ionManager<-align:beansns:bns:bns:bpnt>l-aliorg.sprframework.jdbc.datasource.DataSourceTransa ionManager<-align:beansns:bns:bns:bpnt>(job, <-align:beansns:bns:b<-align:beansns:bns:b<-align:beansns:bns:bns:bpnt>(job, <-align:beansns:bns:bns:b/tdallt><-align:beansns:bns:bns:bpnt>(job, g .incrpan>&inherit;"t><理域对象<配置CR脚本llt><-align:beansns:bns:bns:bhe>ne将执行HSQLDBCR架构脚本 .incrpa些>g .incrpan>&inherit;"t><理域对象<禁p此行为llt><-align:beansns:bns:bns:b<-align:beansns:bns:b<-align:beansns:bns:b<-align:beansns:bns:bns:bpnt>(job, <-align:beansns:bns:bns:bpnt>(job, <-align:beansns:bns:bns:bpnt>(job, g .incrpan>&inherit;"t><理域对象<可以配置模式的e前缀(默认为BATCH_)llt><-align:beansns:bns:bns:b<-align:beansns:bns:b<-align:beansns:bns:b<-align:beansns:bns:bns:bpnt>(job, <-align:beansns:bns:bns:bpnt>l-aliorg.sprframework.batch.core.launk .support.SimpleJobLaunk er<-align:beansns:bns:bns:bpnt>(job, <-align:beansns:bns:b<-align:beansns:bns:b<-align:beansns:bns:bns:bpnt>(job, <-align:beansns:bns:bns:bpnt>l-aliorg.sprframework.batch.core.launk .support.SimpleJobOperator<-align:beansns:bns:bns:bpnt>(job, <-align:beansns:bns:b<-align:beansns:bns:b<-align:beansns:bns:bns:bpnt>(job, <-align:beansns:bns:bns:bpnt>l-aliorg.sprframework.batch.core.explore.support.JobExplorerFactoryBean <-align:beansns:bns:bns:bpnt>(job, <-align:beansns:bns:b<-align:beansns:bns:b<-align:beansns:bns:bns:bpnt>(job, <-align:beansns:bns:bns:bpnt>l-aliorg.sprframework.batch.core.jsr.JsrJobPa;ome ersCon/ er<-align:beansns:bns:bns:bpnt>(job, <-align:beansns:bns:b<-align:beansns:bns:b<-align:beansns:bns:bns:bpnt>(job, <-align:beansns:bns:bns:bpnt>l-aliorg.sprframework.batch.core.c figuration.support.MapJobRegistry<-align:beansns:bns:bns:bpnt>(job, <-align:beansns:bns:b<-align:beansns:bns:b<-align:beansns:bns:bns:bpnt><-align:beansns:bns:bns:bpnt>l-aliorg.sprframework.beans.factory.c fig.Prop yPlaceholderC figure<-align:beansns:bns:bns:bpnt>(job, ne可p于指定Spr Batch当前支持pCRu何受支持数据库 .incrpa些 得<-align:beansns:bns:b<-align:beansns:bns:btitlfon t><-align:beansns:b nt><-align:beansns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:b<-align:beansns:bns:bns:bns:bns:biallt><-align:beansns:bns:bns:bns:b<-align:beansns:bns:bns:bns:b<-align:beansns:bns:bns:bns:bns:b< nt><-align:beansns:bns:bns:bns:bns:bns:b h5的/f ne上述所有bean都不是可选pCR .incrpa些><-align:bgn:bns:bns:bns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:b<-align:beansns:b容易 ><-align:beans容易 ><-align:b容易 ><-align:b nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<依赖注入ncrpa些ONED任h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne虽然没有明确要求正式的依赖注入实p>ne但暗含了某种形式的DI .incrpa些><-align:bgn:b nt><-align:beansns:b<-align:beansns:bns:b<-align:beansns:bns:bns:b h5的/f ne因此支持JSR-352批处理作中的Spr依赖项注入 .incrpa些 得知titlfon t><-align:beansns:bns:b<-align:beansns:bns:bns:b h5的/f ne该文件提供了逻辑名和p名之间pCR映R .incrpa些>ne则必须在/ META-INF /目录中找到该文件 .incrpa些 得知titlfon t><-align:beansns:bns:b<-align:beansns:bns:bns:b h5的/f <-align:beansns:b<-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne作就可以引p它们>ne就像在batch.xml中定义的u何bean一样 .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansn :b< nt><-align:bgn:bns:b< nt> <span nt>ospan>xmln<>ospan>=span nt>"http://www.sprframework.org/schema/beans" ns:b:bns:bxmln<:xsi>ospan>=span nt>"http://www.w3.org/2001/XMLSchema-instunke" ns:b:bns:bxsi:schemaLocation=span nt>"http://www.sprframework.org/schema/beans ><-align:bgn:bns:bns:bns:bnshttps://www.sprframework.org/schema/beans/spr-beans.xsd ><-align:bgn:bns:bns:bns:bnshttp://xmln<.jcp.org/xml/ns/javaee ><-align:bgn:bns:bns:bns:bnshttps://xmln<.jcp.org/xml/ns/javaee/jobXML_1_0.xsd">ospan>> ns:b<span nt>id>ospan>=span nt>"fooBatchlet">ospan>nt><>ospan>=span nt>"io.spr.FooBatchlet">ospan>> ns:bns:bns:b<span nt>ospan>name=span nt>"prop">ospan>value=span nt>"bar">ospan>/> ns:b</span nt>ospan>> ns:b<span nt>id>ospan>=span nt>"fooJob">ospan>xmln<>ospan>=span nt>"http://xmln<.jcp.org/xml/ns/javaee">ospan>vtision=span nt>"1.0">ospan>> ns:bns:bspan nt><span nt>id>ospan>=span nt>"step1">ospan>> ns:bns:bns:b<span nt>a>ospan>=span nt>"fooBatchlet">ospan>/> ns:bns:b</span nt>> ns:b</span nt>> </span nt>><<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b< nt><-align:bgn:bns:b< nt>public span nt>nt><>ospan>b<{ ns:bpublic Batchlet span nt> span nt>() b<{new FooBatchlet();"bar">ospan>); ns:bns:breturn>ospan>"1.0">ospan> encoding=span nt>"UTF-8">ospan>?>"fooJob">ospan>"http://xmln<.jcp.org/xml/ns/javaee">ospan>"1.0">ospan>>"step1">ospan> >"fooBatchlet">ospan><-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f neSpr上下文>n导入等)的组装也可与JSR-352作一起住phe .incrpa些>ne上下文定义的入口点将是在/ META-INF /<-align:bgn:b nt><-align:beansns:b h5的/f ne当住phe这种方法或batch.xml方法时>ne所引p的类要求住phe无参数构造函数来创建Bean .incrpa些 得瘓 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b< nt> <span nt>id>ospan>=span nt>"fooJob">ospan>xmln<>ospan>=span nt>"http://xmln<.jcp.org/xml/ns/javaee">ospan>vtision=span nt>"1.0">ospan>> ns:bspan nt><span nt>id>ospan>=span nt>"step1">ospan> > ns:bns:bspan nt><span nt>a>ospan>=span nt>"io.spr.FooBatchlet">ospan> /> ns:b</span nt>> </span nt>><<-align:beans 容易 ><-align:beans容易 ><-align:b容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<批次属性t/ nt>gONED任h3易 ><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<物支持<-align:beansns:b< nt><-align:beansns:bns:b h5的/f neStep和Batch工件级别上定义属性 .incrpa些>he方式在每up别上配置>nahopjjp= 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b< nt><span nt>> ns:bspan nt><span nt>ospan>name=span nt>"prop yName1">ospan>value=span nt>"prop yValue1">ospan>/> ns:b<span nt>ospan>name=span nt>"prop yName2">ospan>value=span nt>"prop yValue2">ospan>/> </span nt>><<-align:beans eans容易 ><-align:bgn:bns:b<容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b<-align:bgn:b容易 ><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<@BatchProp y批注ncrpa些 h4allt><-align:beansns:b< nt><-align:beansns:bns:bg .incrpan>&inherit;"t><理域对象<类字段进encrpa些>ne从encrpa些><-align:beans eansrpa些>ne属性CR字段必须为Str类型 .incrpa些><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f ne因此访问pCRuu>nahopjjp= 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b< nt>public span nt>nt><>ospan>ex end<>ospan><{ ns:b ns:b ns:bprivate Str prop yName1;<-align:beans eans容易 ><-align:bgn:bns:b<容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b<-align:bgn:b容易 ><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<财产替代<-align:beansns:b< nt><-align:beansns:bns:b h5的/f <-align:bgn:bns:b<容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:bnahopjjp= 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:b<-align:beansns:bns:b<-align:beansns:b<-align:bgn:bns:b< nt><-align:beansns:bns:b< nt>na#{systemProp ies ['fieanse a;otor']}<-align:beans eans容易 ><-align:bgn:bns:b<容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:bne右侧是默认值 .incrpa些><-align:beans eansrpa些ONED任l-ali#{jobPa;ome ers['unresolv.prop']}ne则将返回upStr .incrpa些>ne以“;”分隔 .incrpa些 得知titlfon t><-align:bgn:b容易 ><-align:b容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<加工模型ncrpa些ONED任h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f <-align:bgn:b nt><-align:beansns:b<-align:beansns:bns:b<-align:beansns:bns:bns:b h5的/f ne可选ncrpa些ONED任l-alijavax.batch.api.chunk.ItemProcesnor<-align:beans eansliallt><-align:beansns:bns:b<-align:beansns:bns:bns:b h5的/f <-align:beansns:bns:bns:bns:b实p .incrpa些>g .incrpan>&inherit;"t><理域对象<-align:beans eansliallt><-align:beansns:b<-align:beans容易 ><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<基于项目的处理<-align:beansns:b< nt><-align:beansns:bns:b h5的/f he>ne基于项目的处理是由读取pCR项目数设置CR块大小 ><-align:beans eansrpa些ONED任l-aliItemReaderne请指定 ><-align:beans eansrpa些ONED任l-ali-fem-countne并可以选择配置 ><-align:beans eansrpa些ONED任l-alicheckpoint-policy<-align:bgn:bns:b<容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b< nt><span nt>id>ospan>=span nt>"step1">ospan>> ns:b<span nt>ospan>heckpoint-policy=span nt>"ifem">ospan>-fem-count=span nt>"3">ospan>> ns:bns:bspan nt><span nt>a>ospan>=span nt>"fooReader">ospan>/> ns:bns:b<span nt>a>ospan>=span nt>"fooProcesnor">ospan>/> ns:bns:b<span nt>a>ospan>=span nt>"fooWh-fer">ospan>/> ns:b</span nt>ospan>> </span nt>> ... <-align:beans eans容易 ><-align:bgn:bns:b<容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:bnerpa些ONED任l-alitime-limi g .incrpan>&inherit;"t><理域对象< .incrpa些>ne则块将完成>ne但是届时将读取许多项目,无论将rpa些ONED任l-ali-fem-count<-align:beans <-align:bgn:b容易 ><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<自定义检查点<-align:beansns:b< nt><-align:beansns:bns:b h5的/f ne基于项目的检查点是种方法 .incrpa些>ne这在许多情况>he不够鲁棒 .incrpa些>ne该规范允许通过实pncrpa些ONED任l-alijavax.batch.api.chunk.CheckpointAlgo g .incrpan>&inherit;"t><理域对象< .incrpa些>ne请住phe自定义配置eCR步骤>ne ><-align:beans eansrpa些ONED任l-alicheckpoint-policyne其中ncrpa些ONED任l-alifooCheckpointer<-align:bgn:bns:b<容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b< nt><span nt>id>ospan>=span nt>"step1">ospan>> ns:b<span nt>ospan>heckpoint-policy=span nt>"custom">ospan>> ns:bns:bspan nt><span nt>a>ospan>=span nt>"fooCheckpointer">ospan>/> ns:bns:b<span nt>a>ospan>=span nt>"fooReader">ospan>/> ns:bns:b<span nt>a>ospan>=span nt>"fooProcesnor">ospan>/> ns:bns:b<span nt>a>ospan>=span nt>"fooWh-fer">ospan>/> ns:b</span nt>ospan>> </span nt>> ... <-align:beans eans容易 ><-align:bgn:bns:b<容易 ><-align:bgn:b容易 ><-align:b容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<运行工作ncrpa些ONED任h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f <-align:bgn:bns:b<-align:bgn:b nt><-align:beansns:b< nt>long"fooJob">ospan>,new Prop ies());<-align:beans 容易 ><-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f he操作ahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b<-align:beansns:bns:b<-align:beansns:bns:bns:b h5的/f <-align:beans eansliallt><-align:beansns:bns:b<-align:beansns:bns:bns:b h5的/f g .incrpan>&inherit;"t><理域对象<加载ut/ nt>g .incrpan>&inherit;"t><理域对象<-在上面的示例u,框架将在/ META-INF /ne并加载u上下文>ne该上下文是前面提到pCR共享u下文pCR子级 .incrpa些 得知titlfon t><-align:beansns:bns:b<-align:beansns:bns:bns:b h5的/f <-align:beans eansliallt><-align:beansns:b<-align:beans容易 ><-align:bgn:b nt><-align:beansns:b<-align:beansns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:biallt><-align:beansns:bns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:b< nt><-align:beansns:bns:bns:bns:bns:b h5的/f <-align:bgn:bns:bns:bns:b<-align:beansns:bns:b<-align:beansns:bns:b<-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f <-align:bgn:bns:b<-align:beans容易 ><-align:b容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<语境ncrpa些ONED任h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f nnerpa些ONED任l-aliItemReaderne ><-align:beans n<-align:bgn:b容易 ><-align:bgn:b nt><-align:beansns:b h5的/f gONED任l-aliJobC ext<-align:beansns:bns:b在当前范围内CRncrpa些>ne只需住phencrpa些ONED任l-ali@Inje <-align:bgn:b nt><-align:beansns:b< nt>iallt><-align:beansns:bns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:b< nt><-align:bgn:bns:bns:bns:bns:b< nt><-align:beansns:bns:bns:bns:bns:b h5的/f <-align:bgn:bns:bns:bns:b<-align:beansns:bns:b<-align:beansns:bns:b<-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f gONED任l-aliJobC ext<-align:beans容易 ><-align:b容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<步流<-align:bgn:b nt><-align:beansns:b h5的/f ne有u细微CR差异ahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b<-align:beansns:bns:b<-align:beansns:bns:bns:b h5的/f g .incrpan>&inherit;"t><理域对象<没有CRncrpa些>ne对于JSR-352,决策就是步骤与其他任何步骤u样>ne其e为也将与其他任何步骤u样>n交易性>ne得到ncrpa些ONED任l-aliStepExecution<-align:beansns:bns:b<-align:beansns:bns:bns:bne并且>he一u属性在评估u优先住phe .incrpa些 得知titlfon t><-align:beansns:bns:b<-align:beansns:bns:bns:b h5的/f ne并按该顺序进e评估 .incrpa些><-align:beans eansliallt><-align:beansns:b<-align:beans容易 ><-align:b容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<扩展JSR-352批处理作<-align:bgn:b nt><-align:beansns:b h5的/f n后两种可以e多uJVM执行)>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b<-align:beansns:bns:b<-align:beansns:bns:bns:b h5的/f <-align:beansns:bns:b<-align:beansns:bns:bns:b h5的/f <-align:beansns:bns:b<-align:beansns:bns:bns:b h5的/f n经理/工人) .incrpa些 得瘓 ><-align:bgn:bns:bns:bliallt><-align:beansns:bns:b<-align:beansns:bns:bns:b h5的/f <-align:beans eansliallt><-align:beansns:b<-align:beans容易 ><-align:bgn:b nt><-align:beansns:b h5的/f nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b<-align:beansns:bns:b<-align:beansns:bns:bns:b h5的/f <-align:bgn:bns:bns:bliallt><-align:beansns:bns:b<-align:beansns:bns:bns:b h5的/f ne但是实p上略有同 .incrpa些 得瘓 ><-align:beans eansliallt><-align:beansns:b<-align:beans容易 ><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<分区<-align:beansns:b< nt><-align:beansns:bns:b h5的/f neJSR-352中CR分区与Spr Batch中CR分区相同 .incrpa些>ne工作u员在完成后将结果报告给经理 .incrpa些>ne有u重要pCR区别ahopjjp= 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:b<-align:bgn:bns:bns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:bne ><-align:beans eansns:bns:bne该数组<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:bn分区属性) .incrpa些>ne该接口类似于ncrpa些ONED任l-aliorg.sprframework.batch.core. a;ti ion.support.Pa;ti ioner<-align:beansns:bns:bns:bns:bns:bSpr Batch提供ncrpa些><-align:beans eansns:bns:bne因为它提供了一种以编程方式生成用于分区CR元数据的方法 .incrpa些 得知titlfon t><-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:bne分区步骤是经理/工作u员运行的 .incrpa些>ne会发生相同pCR配置 .incrpa些>ne工人CR步骤并没有得到正式批准rpa些ONED任l-aliStepExecutionsne对的调phe ><-align:bgn:bns:beansns:bns:b<-align:beansns:bns:b<-align:beansns:b<-align:bgn:bns:b< nt><-align:beansns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:b<-align:beansns:bns:bns:bns:bns:biallt><-align:beansns:bns:bns:bns:b<-align:beansns:bns:bns:bns:b<-align:beansns:bns:bns:bns:bns:b< nt><-align:beansns:bns:bns:bns:bns:bns:b h5的/f gONED任l-aliStepExecutionsne可通过ncrpa些ONED任l-aliJobExplorer<-align:bgn:bns:bns:bns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:b<-align:beansns:b<容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:bgONED任l-aliStepExecutionLis enersg .incrpan>&inherit;"t><理域对象<分区的管理器/工作器逻辑,ncrpa些>ne由于工作u员JSR-352提供了其他组件CR集合>ne因此能够在发生错误时提供补偿逻辑并动态设置退出p态 .incrpa些><-align:beansns:bns:b<-align:beansns:b<-align:bgn:bns:b<-align:beansns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:btitlfon t><-align:beansns:bns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:b<-align:beansns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:b<-align:beansns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bne该端点<-align:beansns:bns:b<-align:beansns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:b<-align:beansns:bns:btitlfon t><-align:beans容易 ><-align:b容易 ><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<测试中ncrpa些ONED任/h3易 ><-align:bgn:b nt><-align:beansns:b h5的/f ne因此很难确定uu时完成 .incrpa些>ne将rpa些ONED任l-aliJobExecution<-align:b容易 ><-ali容易 ><容易 >< nt><-aliJoo hunk } : e e>Jo系轻- } h5的/f <-ali< nt><-alins:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<-align:bgn:b nt><-align:beansns:b h5的/f ne但可以通过住pheSpr Integration来高效>ne简洁地实p这些要求 .incrpa些>ne并需要一种有效地集成两u框架的方法 .incrpa些>he>ne出p了几种模式和用例,Spr Batch Integration解决了这些需求 .incrpa些 得知titlfon t><-align:bgn:b nt><-align:beansns:b h5的/f ne但是有条建议可以帮助您a考虑粒度>ne并应用通phe模式 .incrpa些><-align:bgn:b nt><-align:beansns:b h5的/f ne可以实p操作的自动化以及关键问题CR分离和制定p略 .incrpa些>ne当作完成或失败时>ne该事件可能u触发消息发送>ne并且这些消息CR住phe者可能u遇到与应用程序本身无关的操作问题 .incrpa些><-align:bgn:b nt><-align:beansns:b h5的/f he关键概念>nahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b<-align:beansns:bns:b<-align:beansns:bns:bns:bJo系轻- }Namespace SupportaM瘓 ><-align:beans eansliallt><-align:beansns:b<-align:beans容易 ><-align:bgn:b c inue-sn ion-rjn bnt><-align:beansns:b<-align:beansns:bns:b<-align:beansns:bns:bns:bJo系轻- }M> h5的/f <-align:beans eansliallt><-align:beansns:bns:b<-align:beansns:bns:bns:bJo系轻- }M> h5的/f <-align:beans eansliallt><-align:beansns:bns:b<-align:beansns:bns:bns:bJo系轻- }M> h5的/f <-align:beans eansliallt><-align:beansns:bns:b<-align:beansns:bns:bns:bJo系轻- }M> h5的/f <-align:beans eansliallt><-align:beansns:b<-align:beans容易 ><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- }<-align:beansns:b< nt><-align:beansns:bns:b

            Since Spr Batch Integration 1.3, dedated XML Namespacellt><-align:beansns:bns:bns:bsupport was added, with the aim to provide an easier c figurationllt><-align:beansns:bns:bns:bexpp <-align:beansns:bns:bns:bnamespace dentrations to your Spr XML Application C extllt><-align:beansns:bns:bns:bfile:得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b< nt><beans xmlns=span nt>"http://www.sprframework.org/schema/beans">ospan>lltxmlns:xsi=span nt>"http://www.w3.org/2001/XMLSchema-instunke">ospan>lltxmlns:batch-int=span nt>"http://www.sprframework.org/schema/batch-integration">ospan>lltxsi:schemaLocation=span nt>"llt>ospan>><...</beans><-align:beans eans容易 ><-align:bgn:bns:b<容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b

            A fully c figured Spr XML Application C extbfile for Sprllt><-align:beansns:bns:bns:bBatch Integration may look like the follow:得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b< nt><beans xmlns=span nt>"http://www.sprframework.org/schema/beans">ospan>lltxmlns:xsi=span nt>"http://www.w3.org/2001/XMLSchema-instunke">ospan>lltxmlns:int=span nt>"http://www.sprframework.org/schema/integration">ospan>lltxmlns:batch=span nt>"http://www.sprframework.org/schema/batch">ospan>lltxmlns:batch-int=span nt>"http://www.sprframework.org/schema/batch-integration">ospan>lltxsi:schemaLocation=span nt>"llt>ospan>><...</beans><-align:beans eans容易 ><-align:bgn:bns:b<容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b

            Append vtision numbtis to the aerenced XSDbfile is alsollt><-align:beansns:bns:bns:ballowed, but, as a vtision-less dentrationbalways uses thellt><-align:beansns:bns:bns:blatest schema, we generally do not acommend append the vtisionllt><-align:beansns:bns:bns:bnumbti to the XSDbname. Add a vtision numbtillt><-align:beansns:bns:bns:bcould possibly crete issues when updat the Spr Batchllt><-align:beansns:bns:bns:bIntegration dependencies, as they may requiremore acent vtisionsllt><-align:beansns:bns:bns:bof the XML schema.得知titlfon t><-align:bgn:b容易 ><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<通过消息启动批处理作<-align:beansns:b< nt><-align:beansns:bns:b h5的/f ne基本上有u选项ahopjjp= 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:bne住phes<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:b<-align:beansns:bns:b<-align:beansns:b<-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f <-align:beansns:bns:bne您也可以ncrpa些ONED任l-aliJobOperator<-align:beansns:bns:bn .incrpa些>ne更复杂的用例呢?ncrpa些>nFTP服务器以检索批处理作CR数据>ne或者eCR应用程序必须同时支持多u同CR数据源 .incrpa些>n还可以从FTP和其他来源接收数据文件 .incrpa些><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f ne住pheSpr Integration及其众多适配器来执行批处理作将更加强大 .incrpa些>ne并在输入文件到达后立即启动批处理作 .incrpa些>ne您可以创建住phe多u同适配器CRSpr Integration流>ne仅住phe配置即可轻松地同时从多u源中获取批处理作CR数据 .incrpa些>ne因为它允许对事件进e解耦>ne事件驱动pCR执行llt><-align:beansns:bns:b<-align:beansns:b<-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f ne其有效载荷类型为titlfon t><-align:beansns:bns:bns:b需要启动ncrpa些>gONED任l-aliJobParameters<-align:beansns:bns:bns:b启动Batchuncrpa些>g .incrpan>&inherit;"t><理域对象<必需t/ nt>g .incrpan>&inherit;"t><理域对象<的封装ncrpa些><-align:beansns:b<-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f he图说明了p于启动批处理作CR典型Spr Integration消息流 .incrpa些>Jo系轻- }M> h5的/f n网站<-align:beansns:bns:bns:b提供CR短信图标及其描述CR完整概述 .incrpa些 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b< nt><-align:beansns:bns:bns:b启动批处理作llt><-align:beansns:bns:b</容易 ><-align:bgn:bns:bns:b< nt><f<titleD>M>
  h5的/f  </dalignlassljdg><foftory;/tica     ory;/tip
<t, 图27.启动批处理作<rpa些ONED任/容易 ><-align:bgn:bns:b<容易 ><-align:bgn:bns:b< nt><f<on 4llt><-align:beansns:bns:b<h5人transform-a-file-into-a-joblaunk
requestJoo hunk } : e e>Jo系轻- }<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b< nt>package io.spr.sbi;importspan> org.sprframework.batch.core.Job; importspan> org.sprframework.batch.core.JobParametersBuilder; importspan> org.sprframework.batch.integration.launk .JobLaunk Request; importspan> org.sprframework.integration.annotation.Transformer; importspan> org.sprframework.messag.Message;importspan> java.io.File;public nt>< FileMessageToJobRequest {llt><privte Job job;llt><privte StrbfileParameterName;<public void setFileParameterName {llt><thi<.fileParameterName =bfileParameterName;<}<public void setJob {llt><thi<.job =bjob;<}<ospan>llt><public JobLaunk Request toRequest {<<<<<<<<<new JobParametersBuilder();<<<<<<<<<<<<<return new JobLaunk Request(job,<}<-align:beans eans<<<<<-align:bgn:bns:bns:b<-align:bgn:bns:b<容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:bJoo hunk } : e e>Jo系轻- }<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b h5的/f ne将rpa些ONED任l-aliJobExecution<-align:beans eans<<<<g .incrpan>&inherit;"t><理域对象<实例 .incrpa些>ne则无论实际执行是否成功,都将始终返回它 .incrpa些 得瘓 ><-align:beans eans容易 ><-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b h5的/f <-align:beansns:bns:bns:bns:b返回实例ncrpa些><-align:beans eans<<<<gONED任l-aliTaskExecutor<-align:beansns:bns:b<<<<gONED任l-alisynk ronousn单线程) ><-align:beans eans<<<<gONED任l-aliTaskExecutorne ><-align:beans eansns:bncrpa些ONED任l-aliJobExecution<-align:beans eans<<<<g .incrpan>&inherit;"t><理域对象< .incrpa些><-align:beans eansns:bncrpa些ONED任l-aliasynk ronous<-align:beansns:bns:bns:bns:bne ><-align:beans eansns:bns:bnee户可以采取<-align:beans eansns:bns:bn带<-align:beans eansns:bns:bne请参阅有关Jo系轻- }M> h5的/f <-align:beans eansns:bns:b<-align:beans eans容易 ><-align:bgn:bns:b<容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:bJoo hunk } : e e>Jo系轻- }<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b h5的/f he配置创建一u文件 ><-align:beans eansns:bncrpa些ONED任l-aliinbound-channe daptern它们交给我们CR变压器>nncrpa些ONED任l-aliFileMessageToJobRequest<-align:beans eans容易 ><-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b< nt><-align:bgn:bns:bns:bns:b< nt><int:channe id=span nt>"inboundFileChanne ">ospan>/> <int:channe id=span nt>"outboundJobRequestChanne ">ospan>/> <int:channe id=span nt>"jobLaunk ReplyChanne ">ospan>/><int-file:inbound-channe dapter id=span nt>"filePoller">ospan>llt><channe =span nt>"inboundFileChanne ">ospan>llt><directory=span nt>"file:/tmp/myfiles/">ospan>llt><filename-pattern=span nt>"*.csv">ospan>>llt<int:poller fixed-rte=span nt>"1000">ospan>/> </int-file:inbound-channe dapter><int:transformer>ospan> input-channe =span nt>"inboundFileChanne ">ospan>llt><output-channe =span nt>"outboundJobRequestChanne ">ospan>>llt<bean>ospan> nt><=span nt>"io.spr.sbi.FileMessageToJobRequest">ospan>>lltlt<prop y>ospan> name=span nt>"job">ospan> a=span nt>"p sonJob">ospan>/>lltlt<prop y>ospan> name=span nt>"fileParameterName">ospan> value=span nt>"input.file.name">ospan>/>llt</bean>ospan>>l</int:transformer>ospan>><batch-int:job-launk -gteway>ospan> request-channe =span nt>"outboundJobRequestChanne ">ospan>llt><reply-channe =span nt>"jobLaunk ReplyChanne ">ospan>/><int:logg-channe dapter hanne =span nt>"jobLaunk ReplyChanne ">ospan>/><-align:beans eans<<<<<-align:bgn:bns:bns:b<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b< nt>M> h5的/f <-align:bgn:bns:bns:bns:b< nt>public FileMessageToJobRequest fileMessageToJobRequest {new FileMessageToJobRequest();"input.file.name">ospan>);<return fileMessageToJobRequest;ospan> public JobLaunk Gteway jobLaunk Gteway {new SimpleJobLaunk er();new SyncTaskExecutor());new JobLaunk Gteway(simpleJobLaunk er);<return jobLaunk Gteway;ospan> public IntegrationFlow integrationFlow {llt><return IntegrationFlows.from(Files.inboundAdapter(span nt>new File(span nt>"/tmp/myfiles">ospan>)).<<<<<<<<<<<<<<<<new SimplePatternFileLjn Filter(span nt>"*.csv">ospan>)),<<<<1000>ospan>).maxMessagesPerPoll(span nt>1>ospan>))).<<<<<<<<<<<<<<<<<<<<<<<<"headers.id + ': ' + payload">ospan>).<<<<<<<<<-align:beans eans<<<<<-align:bgn:bns:bns:b<-align:bgn:bns:b<容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:bJoo hunk } : e e>Jo系轻- }<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b h5的/f <-align:beansns:bns:bns:bncrpa些ONED任l-aliItemReadern例如)以住phe在作参数“ input.file.name”定义CR位置找到CR文件>n如以>hebean所示。组态>nahopjjp= 得知titlfon t><-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b< nt><-align:bgn:bns:bns:bns:b< nt><bean id=span nt>"itemReader">ospan> nt><=span nt>"org.sprframework.batch.item.file.FlatFileItemReader">ospan>llt><scope=span nt>"step">ospan>>llt<prop y>ospan> name=span nt>"resource">ospan> value=span nt>"file://#{jobParameters['input.file.name']}">ospan>/><...</bean>ospan>><-align:beans eans<<<<<-align:bgn:bns:bns:b<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b< nt>M> h5的/f <-align:bgn:bns:bns:bns:b< nt>public ItemReader sampleReader"#{jobParameters[input.file.name]}">ospan>) Strbresource) {new FlatFileItemReader();new FileSystemResource(resource));return flatFileItemReader;<-align:beans eans<<<<<-align:bgn:bns:bns:b<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b h5的/f <-align:beansns:bns:bns:bns:b为Resource属性值>ne并将rpa些ONED任l-aliItemReaderne该支持允许访问titlfon t><-align:beans eans容易 ><-align:bgn:bns:b<容易 ><-align:bgn:b<容易 ><-align:b<容易 ><-align:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<作启动网关CR可p属性<-align:beans< nt><-align:beansns:b h5的/f he属性>ne您可以设置这些属性来控制uahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b<-align:beansns:bns:b<-align:beansns:bns:bns:bne该定义是以>he任一uCR实例>nahopjjp= 得知titlfon t><-align:beansns:bgn:beansns:b<-align:beansns:bns:beansns:bns:b<-align:beansns:bns:bns:bns:bns:bns:b<-align:beansns:bns:bns:bns:bns:b<-align:beansns:bns:bns:bns:bns:bns:b<-align:beansns:bns:bns:bns:bbbbbbbbbbbbb(确切CR实现取决于组件的输入通道是allt><-align:beansns:bns:bns:bns:bns:bns:b<-align:beansns:bns:bns:bns:b<-align:beansns:bns:bns:b<-align:bgn:bns:bns:b<-align:beansns:bns:b<-align:beansns:bns:bns:bne指示端点应在启动时自动启动 .incrpa些><-align:beans eansliallt><-align:beansns:bns:b<-align:beansns:bns:bns:b<-align:beans eansliallt><-align:beansns:bns:b<-align:beansns:bns:bns:bnahopjjp= 得知titlfon t><-align:beansns:bns:b<-align:beansns:bns:bns:bn以毫秒为单位>n .incrpa些>n例如,住phe当前已满CR有界队列通道时>n>ne此属性才适phe .incrpa些>ne请记住,发送到时 ><-align:beans eansns:bncrpa些ONED任l-aliDirectChanne ne调phe发生在发送者CR线程中 .incrpa些>ne发送操作pCR失败可能是由更>he游CR其他组件引起CR .incrpa些><-align:beans eans<<<<g .incrpan>&inherit;"t><理域对象<属性 ><-align:beans eans<<<<g .incrpan>&inherit;"t><理域对象< .incrpa些>ne则属性默认为<emphasis> -1 </ emphasis>>n这意味着默认情况>he,<-align:beans eansliallt><-align:beansns:bns:b<-align:beansns:bns:bns:bn 可选CR .incrpa些><-align:beansns:bns:bns:bns:bbean引phe .incrpa些>he注册CR实例ncrpa些ONED任l-aliid<-align:beans eansns:bne则将引发异常 .incrpa些 得瘓 ><-align:beans eansliallt><-align:beansns:bns:b<-align:beansns:bns:bns:bn指定当此终结点u订户连接到时的调phe顺序<-align:beans eansliallt><-align:beansns:b<-align:beans<容易 ><-align:b<容易 ><-align:b< nt><-align:beansJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<子元素<-align:beans< nt><-align:beansns:b h5的/f <-align:beans ne您必须提供全局默认值<-align:beans n如以>he示例所示ahopjjp= 得知titlfon t><-align:bgn:b nt><-align:beansns:b< nt><-align:bgn:bns:b< nt><batch-int:job-launk -gteway>ospan> request-channe =span nt>"queueChanne ">ospan>llt><reply-channe =span nt>"replyChanne ">ospan><job-launk er=span nt>"jobLaunk er">ospan>>llt<int:poller fixed-rte=span nt>"1000">ospan>>l</batch-int:job-launk -gteway>ospan>><-align:beans <容易 ><-align:bgn:b<容易 ><-align:bgn:b nt><-align:beansns:b< nt>M> h5的/f <-align:bgn:bns:b< nt>"queueChanne ">ospan>, poller = (fixedRte=span nt>"1000">ospan>)) public JobLaunk Gteway sampleJobLaunk Gteway {new JobLaunk Gteway(jobLaunk er());<return jobLaunk Gteway;<-align:beans <容易 ><-align:bgn:b<容易 ><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<通过u息性消息提供反馈ncrpa些ONED任/h4易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f n因此提供进度u息通常很关键 .incrpa些>ne则可能希望通知利p相关者 .incrpa些>he方式收集此u息>nahopjjp= 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bgn:b<-align:beansns:bns:beans<-align:beansns:bns:bns:bns:b h5的/f h动投票hopjjp= 得知titlfon t><-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:b h5的/f 件驱动的听众hopjjp= 得知titlfon t><-align:beansns:bns:b<-align:beansns:b/容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f n例如通过uphellt><-align:beansns:bns:bn>ne将rpa些ONED任l-aliJobExecution<-align:beans eanst/ nt>g .incrpan>&inherit;"t><理域对象<实例 .incrpa些>nellt><-align:beansns:bns:bg .incrpan>&inherit;"t><理域对象<通过uphellt><-align:beansns:bns:b<-align:beans eanst/ nt>g .incrpan>&inherit;"t><理域对象<检索CR更新实例>ne从而连续轮询p态更新g .incrpan>&inherit;"t><理域对象< .incrpa些>n这被认为是次优CR>n因此应首选>件驱动的方法 .incrpa些 l-aliJobRepository<-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f neSpr Batch提供了侦听器>n包括三u最常pheCR侦听器>nahopjjp= 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bgn:b<-align:beansns:bns:beans<-align:beansns:bns:bns:bns:b h5的/f <-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:b h5的/f <-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:b h5的/f <-align:beansns:bns:b<-align:beansns:b/容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f he图所示CR示例中>n已住phe来配置Spr Batch作llt><-align:beansns:bns:bneSpr Integration接收并处理事件u前或u后CR任何步骤 .incrpa些><-align:beans eanst/ nt>g .incrpan>&inherit;"t><理域对象<的内容llt><-align:beansns:bns:bne可能会发生各种情况>n例如,将消息路由到邮件出站通道适配器>n>ne以便可以根据某种条件发送电子邮件通知 .incrpa些 得瘓 ><-align:beans /容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b< nt><-align:beansns:bns:bns:b处理信息性消息ballt><-align:beansns:bns:b</容易 ><-align:bgn:bns:bns:b< nt><f<titleD>M>
  h5的/f  </dalignlassljdg><foftory;/tica     ory;/tip
<t, 图28.处理信息性消息</rpa些ONED任/容易 ><-align:bgn:bns:b</容易 ><-align:bgn:bns:b< nt><f< a;obL<ballt><-align:beansns:bns:b<pM>
  h5的/f  </dalignlassljdg><foftory;/tica     ory;/tip
<t, 以>he两部分组成的实施例示出了收听者是如何配置为发送一u消息给</rpa些ONED任l-aliGteway</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结为u ><-align:beans    eanst/  nt>gONED任l-aliStepExecution</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结事件>ne并且其输出记录到u ><-align:beans    eanst/  nt>gONED任l-alilogg-channe   dapter</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结 .incrpa些      得瘓 ><-align:beans    </容易 ><-align:bgn:bns:b< nt><f< a;obL<ballt><-align:beansns:bns:b<pM>
  h5的/f  </dalignlassljdg><foftory;/tica     ory;/tip
<t, 首先>ne创建通知集成Bean>nahopjjp=      得知titlfon t><Mageans/容易 ><-align:bgn:bns:b< nt><f<rjn block xmlC   ent<-align:beansns:bns:b< nt><-align:bgn:bns:bns:b< nt><int:channe id=span nt>"stepExecutionsChanne ">ospan>/><int:gteway>ospan> id=span nt>"notifationExecutionsLjn ener">ospan>llt><service-interface=span nt>"org.sprframework.batch.core.StepExecutionLjn ener">ospan>llt><default-request-channe =span nt>"stepExecutionsChanne ">ospan>/><int:logg-channe dapter hanne =span nt>"stepExecutionsChanne ">ospan>/><-align:beans eans/容易 ><-align:bgn:bns:b<-align:bgn:bns:b< nt><-align:beansns:bns:b< nt>M> h5的/f <-align:bgn:bns:bns:b< nt>"stepExecutionsChanne ">ospan>) public LoggHandler loggHandler {new LoggHandler(LoggHandler.Level.WARN);< dapter.setLoggerName(span nt>"TEST_LOGGER">ospan>);< dapter.setLogExpressionStr(span nt>"headers.id + ': ' + payload">ospan>); lt><return dapter;(name = "notifationExecutionsLjn ener">ospan>, defaultRequestChanne = "stepExecutionsChanne ">ospan>) public interface NotifationExecutionLjn ener ex ends StepExecutionLjn ener {}<-align:beans eans/容易 ><-align:bgn:bns:b<-align:bgn:bns:b< nt><-align:beansns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:b<-align:beansns:bns:bns:bns:bns:b<-align:beansns:bns:b< nt><-align:bgn:bns:bns:b< nt><job id=span nt>"importPaymentsD>ospan>>lltlt<step id=span nt>"step1D>ospan>>lltltltlt<tasklet ..>ospan>/> ><-align:b<chunk ..>ospan>/> ><-align:b<ljn eners>ospan>>lltltltlt-align:b<ljn ener>ospan> re=span nt>"notifationExecutionsLjn ener">ospan>/> ><-align:b</ljn eners>ospan>>lltltltlt</tasklet><<<<<...</step>l</job><-align:beans eans/容易 ><-align:bgn:bns:b<-align:bgn:bns:b< nt><-align:beansns:bns:b< nt>M> h5的/f <-align:bgn:bns:bns:b< nt>public Job importPaymentsJob { lt><return jobBuilderFactory.get(span nt>"importPaymentsD>ospan>)<<<<<.start(stepBuilderFactory.get(span nt>"step1D>ospan>)<<<<<<<<<.chunk(span nt>200>ospan>)<<<<<<<<<.ljn ener(notifationExecutionsLjn ener())<<<<<<<<<...<-align:beans eans/容易 ><-align:bgn:bns:b<-align:bgn:b<容易 ><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<异步处理器hopjjp= h4易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f nan ><-align:beans eanst/ nt>gONED任l-aliAsyncItemProcessorg .incrpan>&inherit;"t><理域对象<逻辑g .incrpan>&inherit;"t><理域对象< .incrpa些>ne将rpa些ONED任l-aliFuturegONED任l-aliAsynchItemWh-fer<-align:beans /容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f ne您可以通过uphe异步项目处理来提高性能>ne从根本上允许您实现 ><-align:beans eanst/ nt>gONED任em (job, <-align:beans eanst/ nt>gONED任l-aliAsyncItemWh-ferne并很快写回块的所有结果变得可p .incrpa些 得瘓 ><-align:beans /容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f he示例显示了如何配置t/ nt>gONED任l-aliAsyncItemProcessornahopjjp= 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b< nt><-align:bgn:bns:bns:b< nt><bean id=span nt>" rocessor">ospan>llt><nt><=span nt>"org.sprframework.batch.integration.async.AsyncItemProcessor">ospan>>llt<prop y>ospan> name=span nt>"delegteD>ospan>>lltlt<bean nt><=span nt>"your.ItemProcessor">ospan>/>llt</prop y>ospan>>llt<prop y>ospan> name=span nt>"taskExecutor">ospan>>lltlt<bean nt><=span nt>"org.sprframework.core.task.SimpleAsyncTaskExecutor">ospan>/>llt</prop y>ospan>>l</bean>ospan>><-align:beans eans/容易 ><-align:bgn:bns:b<-align:bgn:bns:b< nt><-align:beansns:bns:b< nt>M> h5的/f <-align:bgn:bns:bns:b< nt>public AsyncItemProcessor processor {new AsyncItemProcessor();<return asyncItemProcessor;<-align:beans eans/容易 ><-align:bgn:bns:b<-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f n该ncrpa些ONED任l-alitaskExecutor<-align:beans /容易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f he示例显示了如何配置t/ nt>gONED任l-aliAsyncItemWh-fernahopjjp= 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bns:b< nt><-align:bgn:bns:bns:b< nt><bean id=span nt>"itemWh-fer">ospan>llt><nt><=span nt>"org.sprframework.batch.integration.async.AsyncItemWh-fer">ospan>>llt<prop y>ospan> name=span nt>"delegteD>ospan>>lltlt<bean id=span nt>"itemWh-fer">ospan> nt><=span nt>"your.ItemWh-fer">ospan>/>llt</prop y>ospan>>l</bean>ospan>><-align:beans eans/容易 ><-align:bgn:bns:b<-align:bgn:bns:b< nt><-align:beansns:bns:b< nt>M> h5的/f <-align:bgn:bns:bns:b< nt>public AsyncItemWh-fer wh-fer {new AsyncItemWh-fer();<return asyncItemWh-fer;<-align:beans eans/容易 ><-align:bgn:bns:b<-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f n该ncrpa些ONED任l-alidelegteg .incrpan>&inherit;"t><理域对象<的引phencrpa些 .incrpan>&inherit;"t><理域对象< .incrpa些 得知titlfon t><-align:bgn:b<容易 ><-align:bgn:b nt><-align:beansns:bJoo hunk } : e e>Jo系轻- } h5的/f g .incrpan>&inherit;"t><理域对象<外化批处理执行ncrpa些 h4易 ><-align:bgn:bns:b< nt><-align:beansns:bns:b h5的/f ne其中Spr Integration像外壳一样包装Spr Batch .incrpa些>nSpr Batch也可以在内部住pheSpr Integration .incrpa些>nSpr Batchphe户可以将项目或u至块的处理委托给外部流程 .incrpa些>he方面提供了专门的支持>nahopjjp= 得知titlfon t><-align:bgn:bns:b< nt><-align:beansns:bgn:b<-align:beansns:bns:beans<-align:beansns:bns:bns:bns:b h5的/f <-align:beansns:bns:bns:b<-align:beansns:bns:bns:bns:b h5的/f <-align:beansns:bns:b<-align:beansns:b/容易 ><-align:bgn:bns:b< nt><-align:beansns:bgn:be>Joo hunk } : e e>Jo系轻- }aM> h5的/f <-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b< nt><-align:beansns:bns:bns:bns:b远程分块ballt><-align:beansns:bns:bns:b</容易 ><-align:bgn:bns:bns:bns:b< nt><f<titleD>M>
  h5的/f  </dalignlassljdg><foftory;/tica     ory;/tip
<t, 图29.远程分块hopjjp=      容易 ><-align:bgn:bns:bns:b</容易 ><-align:bgn:bns:bns:b< nt><f< a;obL<ballt><-align:beansns:bns:bns:b<pM>
  h5的/f  </dalignlassljdg><foftory;/tica     ory;/tip
<f结更进一步>ne人还可以住phe</rpa些ONED任l-aliChunkMessageChanne ItemWh-fer</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结llt><-align:beansns:bns:bns:bns:b(由Spr Batch Integration提供)t/  nt>g .incrpan>&inherit;<理域对象<将块处理外部化llt><-align:beansns:bns:bns:bg .incrpan>&inherit;"t><理域对象<>ne后者将项目发送出去并收集结果 .incrpa些>neSpr Batchp续读取和分组项目pCR过程>n而无需等待结果 .incrpa些>n负责<-align:beansns:bns:bns:bns:b收集结果并将其重新集成到Spr Batch流程中 .incrpa些ONED任知titlfon t><-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b h5的/f ne您可以e全控制进程pCR并发性>n例如,住phe<-align:beansns:bns:bns:bgONED任l-aliDirectChanne n .incrpa些>n例如JMS和AMQP>n>ne您可以将Batch作pCR块分发到外部系统进e处理 .incrpa些ONED任知titlfon t><-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b h5的/f ne其配置可能类似于>he内容>nahopjjp= 得知titlfon t><-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b< nt><-align:bgn:bns:bns:bns:b< nt><job id=span nt>"personJob">ospan>>llt<step id=span nt>"step1D>ospan>>lltlt<tasklet>lltltlt<chunk reader=span nt>"itemReader">ospan> wh-fer=span nt>"itemWh-fer">ospan> ommit-interva =span nt>"200">ospan>/> ><</tasklet><...</step>l</job><-align:beans eansns:b<-align:bgn:bns:bns:b<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b< nt>M> h5的/f <-align:bgn:bns:bns:bns:b< nt>public Job chunkJob { lt><<return jobBuilderFactory.get(span nt>"personJob">ospan>)<<<<<<.start(stepBuilderFactory.get(span nt>"step1D>ospan>)<<<<<<<<<<.<Person, Person>chunk(span nt>200>ospan>)<<<<<<<<<<.reader(itemReader())<<<<<<<<<<.wh-fer(itemWh-fer())<<<<<<<<<<.build())<<<<<<.build();<-align:beans eanst><<<容易 ><-align:bgn:bns:bns:b<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b h5的/f <-align:beansns:bns:bns:bns:b(称ncrpa些ONED任l-aliChunkMessageChanne ItemWh-fern>ne如上所述 .incrpa些>n保留在管理器配置上>ne就像在工作服务器上配置CR一样 .incrpa些>he配置提供了基本的管理器设置 .incrpa些>n应检查所有其他组件属性,例如节流阀限制等 .incrpa些ONED任知titlfon t><-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b< nt><-align:bgn:bns:bns:bns:b< nt><bean id=span nt>"c nektionFactory">ospan> nt><=span nt>"org.apache.activemq.ActiveMQC nektionFactory">ospan>>llt<prop y>ospan> name=span nt>"brokerURL">ospan> va ue=span nt>"tcp://localhost:61616">ospan>/></bean>ospan>><int-jms:outbound-channe dapter id=span nt>"jmsRequests">ospan> den ation-name=span nt>"requests">ospan>/><bean id=span nt>"messagTemplateD>ospan>llt><nt><=span nt>"org.sprframework.integration.core.MessagTemplateD>ospan>>llt<prop y>ospan> name=span nt>"defaultChanne ">ospan> re=span nt>"requests">ospan>/>llt<prop y>ospan> name=span nt>"receiveTimeout">ospan> va ue=span nt>"2000">ospan>/></bean>ospan>><bean id=span nt>"itemWh-fer">ospan>llt><nt><=span nt>"org.sprframework.batch.integration.chunk.ChunkMessageChanne ItemWh-fer">ospan>llt><scop =span nt>"stepD>ospan>>llt<prop y>ospan> name=span nt>"messagOp ations">ospan> re=span nt>"messagTemplateD>ospan>/>llt<prop y>ospan> name=span nt>"replyChanne ">ospan> re=span nt>"replies">ospan>/>l</bean>ospan>><int:channe id=span nt>"replies">ospan>>llt<int:queue>ospan>/>l</int:channe ><int-jms:message-driven-channe dapter id=span nt>"jmsReplies">ospan>llt><den ation-name=span nt>"replies">ospan>llt><hanne =span nt>"replies">ospan>/><-align:beans eansns:b<-align:bgn:bns:bns:b<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b< nt>M> h5的/f <-align:bgn:bns:bns:bns:b< nt>public org.apache.activemq.c nektionFactory {new ActiveMQC nektionFactory();"tcp://localhost:61616">ospan>); lt><return factory;ospan> ospan> public DirectChanne requests { lt><return new DirectChanne ();ospan> public IntegrationFlow outboundFlow { lt><return IntegrationFlows<<<<<.from(requests())<<<<<.handle(Jms.outboundAdapter(c nektionFactory).den ation(span nt>"requests">ospan>))<<<<<.get();ospan> ospan> public QueueChanne replies { lt><return new QueueChanne ();ospan> public IntegrationFlow inboundFlow { lt><return IntegrationFlows<<<<<.from(Jms.messageDrivenChanne Adapter(c nektionFactory).den ation(span nt>"replies">ospan>))<<<<<.hanne (replies())<<<<<.get();ospan> ospan> public ItemWh-fer<Integer> itemWh-fer {new MessagTemplate();2000>ospan>);<<<<<= new ChunkMessageChanne ItemWh-fer<>();<return chunkMessageChanne ItemWh-fer;<-align:beans eanslt><<容易 ><-align:bgn:bns:bns:b<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b h5的/f ne我们ncrpa些ONED任l-aliitemWh-fern它住phellt><-align:beansns:bns:bns:bgONED任l-aliChunkMessageChanne ItemWh-fer<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b h5的/f ne我们可以p续进e工作程序配置>ne如以>he示例所示>nahopjjp= 得知titlfon t><-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b< nt><-align:bgn:bns:bns:bns:b< nt>sf<bean id=span nt>"c nektionFactory">ospan> nt><=span nt>"org.apache.activemq.ActiveMQC nektionFactory">ospan>>llt<prop y>ospan> name=span nt>"brokerURL">ospan> va ue=span nt>"tcp://localhost:61616">ospan>/></bean>ospan>><int:channe id=span nt>"requests">ospan>/>l<int:channe id=span nt>"replies">ospan>/><int-jms:message-driven-channe dapter id=span nt>"inc mRequests">ospan>llt><den ation-name=span nt>"requests">ospan>llt><hanne =span nt>"requests">ospan>/><int-jms:outbound-channe dapter id=span nt>"outgoReplies">ospan>llt><den ation-name=span nt>"replies">ospan>llt><hanne =span nt>"replies">ospan>>l</int-jms:outbound-channe dapter><int:service-activator id=span nt>"serviceActivator">ospan>llt><input-hanne =span nt>"requests">ospan>llt><output-hanne =span nt>"replies">ospan>llt><re=span nt>"chunkProcessorChunkHandler">ospan>llt><method=span nt>"handleChunk">ospan>/><bean id=span nt>"chunkProcessorChunkHandler">ospan>llt><nt><=span nt>"org.sprframework.batch.integration.chunk.ChunkProcessorChunkHandler">ospan>>llt<prop y>ospan> name=span nt>"chunkProcessor">ospan>>lltlt<bean nt><=span nt>"org.sprframework.batch.core.step.item.SimpleChunkProcessor">ospan>>lltltlt<prop y>ospan> name=span nt>"itemWh-fer">ospan>>lltltltlt<bean nt><=span nt>"io.spr.sbi.PersonItemWh-fer">ospan>/>lltltlt</prop y>ospan>>lltltlt<prop y>ospan> name=span nt>"itemProcessor">ospan>>lltltltlt<bean nt><=span nt>"io.spr.sbi.PersonItemProcessor">ospan>/>lltltlt</prop y>ospan>>lltlt</bean>ospan>> ns</prop y>ospan>>l</bean>ospan>><-align:beans eansltlt<-align:bgn:bns:bns:b<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b< nt>M> h5的/f <-align:beansns:bns:bns:b< nt>public org.apache.activemq.c nektionFactory {new ActiveMQC nektionFactory();"tcp://localhost:61616">ospan>); lt><return factory;ospan> ospan> public DirectChanne requests { lt><return new DirectChanne ();ospan> public IntegrationFlow inboundFlow { lt><return IntegrationFlows<<<<<.from(Jms.messageDrivenChanne Adapter(c nektionFactory).den ation(span nt>"requests">ospan>))<<<<<.channe (requests())<<<<<.get();ospan> ospan> public DirectChanne replies { lt><return new DirectChanne ();ospan> public IntegrationFlow outboundFlow { lt><return IntegrationFlows<<<<<.from(replies())<<<<<.handle(Jms.outboundAdapter(c nektionFactory).den ation(span nt>"replies">ospan>))<<<<<.get();ospan> ospan> ospan>(inputChanne = "requests">ospan>, outputChanne = "replies">ospan>) public ChunkProcessorChunkHandler<Integer> chunkProcessorChunkHandler {<<<<<= new SimpleChunkProcessor<>(itemProcessor(), itemWh-fer());<<<<<= new ChunkProcessorChunkHandler<>();<return chunkProcessorChunkHandler;<-align:beans eanslt><<容易 ><-align:bgn:bns:bns:b<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b h5的/f ne大多数这些配置项应该看起来很熟悉 .incrpa些>gONED任l-aliJobRepositorygONED任l-alichunkProcessorChunkHandlergONED任l-aliChunkProcessorChunkHandlergONED任l-aliSimpleChunkProcessornencrpa些 .incrpan>&inherit;"t><理域对象<该llt><-align:beansns:bns:bns:bg>g>n以及(可选>n您的llt><-align:beansns:bns:bns:bgONED任l-aliItemProcessorg .incrpan>&inherit;"t><理域对象<的引phe>n该引phellt><-align:beansns:bns:bns:bg><-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b h5的/f n请参见“bgONED任aataerhttps://docs.spr.io/spr-batch/aerence/; n;/s abilityn; n;"remoteChunk"nt>Jo系轻- } h5的/f h5的/f <-align:beansns:bns:bns:bg><-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b h5的/f neSpr Batch Integration引入了ncrpa些ONED任l-ali@EnableBatchIntegration<-align:beansns:bns:bns:bns:b可p于简化远程分块设置ncrpa些>he文中自动装配CRbean>nahopjjp= 得知titlfon t><-align:bgn:bns:bns:b< nt><-align:beansns:bgn:bns:b<-align:beansns:bns:beansns:b<-align:beansns:bns:bns:bns:bns:b<-align:beansns:bns:bns:bns:b<-align:beansns:bns:bns:bns:bns:b<-align:beansns:bns:bns:b<-align:beansns:bns:b<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b h5的/f ne如下图所示>nahopjjp= 得知titlfon t><-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b< nt><-align:beansns:bns:bns:bns:b远程分块配置ballt><-align:beansns:bns:bns:b</容易 ><-align:bgn:bns:bns:bns:b< nt><f<titleD>M>
  h5的/f  </dalignlassljdg><foftory;/tica     ory;/tip
<t, 图30.远程分块配置</rpa些ONED任/容易 ><-align:beansns:bns:b</容易 ><-align:bgn:bns:bns:b< nt><f< a;obL<ballt><-align:beansns:bns:bns:b<pM>
  h5的/f  </dalignlassljdg><foftory;/tica     ory;/tip
<f结在管理器端>nncrpa些ONED任l-aliRemoteChunkManagerStepBuilderFactory</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结可以通过声明>he内容来配置管理器步骤>nahopjjp=      得知titlfon t><Mageansns:b</容易 ><-align:bgn:bns:bns:b< nt><f<urjn ballt><-align:beansns:bgn:bns:b<ulallt><-align:beansns:bns:beansns:b<liallt><-align:beansns:bns:bns:bns:bns:b<p(job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结物品阅读器读取物品并将其发送给工人hopjjp=      得知titlfon t><Mageansns:bns:bns:b</liallt><-align:beansns:bns:bns:bns:b<liallt><-align:beansns:bns:bns:bns:bns:b<p>
  h5的/f  </dalignlassljdg><foftory;/tica     ory;/tip
<f结输出通道(“传出请求”)将请求发送给工作人员hopjjp=      得知titlfon t><Mageansns:bns:bns:b</liallt><-align:beansns:bns:bns:bns:b<liallt><-align:beansns:bns:bns:bns:bns:b<p>
  h5的/f  </dalignlassljdg><foftory;/tica     ory;/tip
<f结输入通道(“传入答复”)接收工作人员的答复hopjjp=      得知titlfon t><Mageansns:bns:bns:b</liallt><-align:beansns:bns:bns:b</ulallt><-align:beansns:bns:b</容易 ><-align:bgn:bns:bns:b< nt><f< a;obL<ballt><-align:beansns:bns:bns:b<pM>
  h5的/f  </dalignlassljdg><foftory;/tica     ory;/tip
<f结不需要显式配置</rpa些><foftory;/tica     ory;/tip
<f结Ab</  nt>gONED任l-aliChunkMessageChanne ItemWh-fer</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结和 .incrpa些ONED任eo  MessagTemplate</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结>n如果需要,仍可以显式配置它们>n .incrpa些ONED任知titlfon t><Mageansns:b</容易 ><-align:bgn:bns:bns:b< nt><f< a;obL<ballt><-align:beansns:bns:bns:b<pM>
  h5的/f  </dalignlassljdg><foftory;/tica     ory;/tip
<f结在工作程序端>nncrpa些ONED任l-aliRemoteChunkWorkerBuilder</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结允许您配置工作程序以>nahopjjp=      得知titlfon t><Mageansns:b</容易 ><-align:bgn:bns:bns:b< nt><f<urjn ballt><-align:beansns:bgn:bns:b<ulallt><-align:beansns:bns:beansns:b<liallt><-align:beansns:bns:bns:bns:bns:b<p(job, <s/lasrn: e   </dalignlassljdg><foftory;/tica     ory;/tip
<f结侦听经理在输入通道上发送的请求(“传入请求”)hopjjp=      得知titlfon t><Mageansns:bns:bns:b</liallt><-align:beansns:bns:bns:bns:b<liallt><-align:beansns:bns:bns:bns:bns:b<p>
  h5的/f  </dalignlassljdg><foftory;/tica     ory;/tip
<f结住phe已配置CR</  nt>g><foftory;/   jd予想t><aunch-f结和</  nt>g><foftory;/   jd予想t><aunch-f结为每个请求ncrpa些 .incrpan>&inherit;<理域对象<调phegONED任l-aliChunkProcessorChunkHandler<-align:beansns:bns:bns:bns:b<-align:beansns:bns:bns:bns:bns:b

            h5的/f <-align:beansns:bns:bns:b<-align:beansns:bns:b<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b h5的/f gONED任l-aliChunkProcessorChunkHandlern .incrpa些ONED任知titlfon t><-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b h5的/f he示例显示了如何住phe这些API>nahopjjp= 得知titlfon t><-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b< nt>public nt>< RemoteChunkJobC figuration {< lt><public static nt>< ManagerC figuration {< lt><private RemoteChunkManagerStepBuilderFactory managerStepBuilderFactory;<ospan> lt><public TaskletStep managerStep { lt><return thi<.managerStepBuilderFactory.get(span nt>"managerStepD>ospan>)<<<<<<<<<<><.chunk(span nt>100>ospan>)<<<<<<<<<<<<.reader(itemReader())<<<<<<<<<<<<.outputChanne (requests()) ospan> lt><<<<<<<<.inputChanne (replies())t><<<<<<<<<.build();<<}< lt><public static nt>< WorkerC figuration {< lt><private RemoteChunkWorkerBuilder workerBuilder;<ospan> lt><public IntegrationFlow workerFlow { lt><return thi<.workerBuilder<<<<<<<<.itemProcessor(itemProcessor())<<<<<<<<<<<<.itemWh-fer(itemWh-fer())<<<<<<<<<<<<.inputChanne (requests()) ospan> lt><<<<<<<<.outputChanne (replies())tospan><<<<<<<<.build();<<}<-align:beans eanslt><<容易 ><-align:bgn:bns:bns:b<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b h5的/f gONED任aataerhttps://github.om/spr-projects/spr-batch/tree/masfer/spr-batch-samples#remote-chunk-sample"nt>Jo系轻- } h5的/f h5的/f <-align:beansns:bns:bns:bg><-align:bgn:bns:b<-align:bgn:bns:b< nt><-align:beansns:bns:b

            aant>Jo系轻- }aM> h5的/f <-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b< nt><-align:beansns:bns:bns:bns:b远程分区ballt><-align:beansns:bns:bns:b</容易 ><-align:bgn:bns:bns:bns:b< nt><f<titleD>M>
  h5的/f  </dalignlassljdg><foftory;/tica     ory;/tip
<t, 图31.远程分区hopjjp=      容易 ><-align:bgn:bns:bns:b</容易 ><-align:bgn:bns:bns:b< nt><f< a;obL<ballt><-align:beansns:bns:bns:b<pM>
  h5的/f  </dalignlassljdg><foftory;/tica     ory;/tip
<f结另一方面>ne当不是分区的处理而是导致瓶颈的相关I / O时>n远程分区很有用 .incrpa些><foftory;/   jd予想t><aunch-f结住phe远程分区>ne可以将工作分配给执e完整Spr Batch步骤的工作人员 .incrpa些><foftory;/   jd予想t><aunch-f结因此>ne每个工人都有自己的</rpa些ONED任l-aliItemReader</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结>n</  nt>gONED任l-aliItemProcessor</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结和llt><-align:beansns:bns:bns:b</  nt>gONED任l-aliItemWh-fer</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结 .incrpa些><foftory;/   jd予想t><aunch-f结为此>neSpr Batch Integration提供了ncrpa些ONED任eo  MessageChanne Pa;titionHandler</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结 .incrpa些ONED任知titlfon t><Mageansns:b</容易 ><-align:bgn:bns:bns:b< nt><f< a;obL<ballt><-align:beansns:bns:bns:b<pM>
  h5的/f  </dalignlassljdgONED任eo  Pa;titionHandler</eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结llt><-align:beansns:bns:bns:bns:b接口的</rpa些><foftory;/tica     ory;/tip
<f结此实现ncrpa些><foftory;/   jd予想t><aunch-f结住phencrpa些ONED任eo  MessageChanne </eo   (job, <s/lasrn: e   </dalignlassljdg><foftory;/   jd予想t><aunch-f结实例将指令发送给远程工作人员并接收其响应 .incrpa些><foftory;/   jd予想t><aunch-f结这提供了p于与远程工作者通信CR传输>n如JMS和AMQP)的很好的抽象 .incrpa些ONED任知titlfon t><Mageansns:b</容易 ><-align:bgn:bns:bns:b< nt><f< a;obL<ballt><-align:beansns:bns:bns:b<pM>
  h5的/f  </dalignlassljdg>
  h5的/f  </dalignlassljdg“可伸缩性”一章中涉及llt><-align:beansns:bns:bns:b</  nt>gONED任aataerindex-slen; n;Jo系轻- } h5的/f h5的/f ne并显示了住phe默认值ncrpa些ONED任eo TaskExecutorPa;titionHandler<-align:beansns:bns:bns:bg>ne需要两u附加组件>nahopjjp= 得知titlfon t><-align:bgn:bns:bns:b< nt><-align:beansns:bgn:bns:b<-align:beansns:bns:beansns:b<-align:beansns:bns:bns:bns:bns:b<-align:beansns:bns:bns:bns:b<-align:beansns:bns:bns:bns:bns:b

            h5的/f <-align:beansns:bns:bns:b<-align:beansns:bns:b<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b h5的/f neJMS可以p作“远程处理结构” .incrpa些>ng>g>n请住phencrpa些ONED任eo MessageChanne Pa;titionHandlerhe示例假定现有分区作>ne并着重于ncrpa些ONED任eo MessageChanne Pa;titionHandlernahopjjp= 得知titlfon t><-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b< nt><-align:bgn:bns:bns:bns:b< nt>sf<bean id=span nt>"pa;titionHandler">ospan>llt>nt><=span nt>"org.sprframework.batch.integration.pa;tition.MessageChanne Pa;titionHandler">ospan>>llt<prop y>ospan> name=span nt>"stepName">ospan> va ue=span nt>"step1">ospan>/>llt<prop y>ospan> name=span nt>"gridSize">ospan> va ue=span nt>"3">ospan>/>llt<prop y>ospan> name=span nt>"replyChanne ">ospan> re=span nt>"outbound-replies">ospan>/>llt<prop y>ospan> name=span nt>"messagOp ations">ospan>>lltlt<bean nt><=span nt>"org.sprframework.integration.core.MessagTemplate">ospan>>lltltlt<prop y>ospan> name=span nt>"defaultChanne ">ospan> re=span nt>"outbound-requests">ospan>/>lltltlt<prop y>ospan> name=span nt>"receiveTimeout">ospan> va ue=span nt>"100000">ospan>/>lltlt</bean>ospan>> ns</prop y>ospan>>l</bean>ospan>><int:channe id=span nt>"outbound-requests">ospan>/>l<int-jms:outbound-channe dapter den ation=span nt>"requestsQueue"lltlthanne =span nt>"outbound-requests">ospan>/><int:channe id=span nt>"inbound-requests">ospan>/>l<int-jms:message-driven-channe dapter den ation=span nt>"requestsQueue"lltlthanne =span nt>"inbound-requests">ospan>/><bean id=span nt>"stepExecutionRequestHandler">ospan>llt><nt><=span nt>"org.sprframework.batch.integration.pa;tition.StepExecutionRequestHandler">ospan>>llt<prop y>ospan> name=span nt>"jobExplorer">ospan> re=span nt>"jobExplorer">ospan>/>llt<prop y>ospan> name=span nt>"stepLocator">ospan> re=span nt>"stepLocator">ospan>/></bean>ospan>><int:service-activator re=span nt>"stepExecutionRequestHandler">ospan><input-hanne =span nt>"inbound-requests">ospan>llt><output-hanne =span nt>"outbound-stag">ospan>/><int:channe id=span nt>"outbound-stag">ospan>/>l<int-jms:outbound-channe dapter den ation=span nt>"stagQueue"lltlthanne =span nt>"outbound-stag">ospan>/><int:channe id=span nt>"inbound-stag">ospan>/>l<int-jms:message-driven-channe dapter den ation=span nt>"stagQueue"lltlthanne =span nt>"inbound-stag">ospan>/><int:aggregator re=span nt>"pa;titionHandler">ospan><input-hanne =span nt>"inbound-stag">ospan>llt><output-hanne =span nt>"outbound-replies">ospan>/><int:channe id=span nt>"outbound-replies">ospan>>llt<int:queue>ospan>/></int:channe ><bean id=span nt>"stepLocator">ospan>llt><nt><=span nt>"org.sprframework.batch.integration.pa;tition.BeanFactoryStepLocator">ospan> /><-align:beans eansltlt<-align:bgn:bns:bns:b<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b< nt>M> h5的/f <-align:beansns:bns:bns:b< nt>public Pa;titionHandler pa;titionHandler {new MessageChanne Pa;titionHandler();"step1">ospan>);3>ospan>);new MessagTemplate();100000>ospan>);<return pa;titionHandler;ospan> public QueueChanne outboundReplies { lt><return new QueueChanne ();ospan> public DirectChanne outboundRequests { lt><return new DirectChanne ();ospan> public IntegrationFlow outboundJmsRequests { lt><return IntegrationFlows.from(span nt>"outboundRequests">ospan>)<.handle(Jms.outboundGateway(c nektionFactory())<<<<<<<<<.requestDen ation(span nt>"requestsQueue"))<<<<<.get();ospan> ospan>(inputChanne = "inboundStag">ospan>) public AggregatorFactoryBean pa;titionMessageHandler throws Exception {new AggregatorFactoryBean();ospan>llt><return aggregatorFactoryBean;ospan> public DirectChanne inboundStag { lt><return new DirectChanne ();ospan> public IntegrationFlow inboundJmsStag { lt><return IntegrationFlows<<<<<.from(Jms.messageDrivenChanne Adapter(c nektionFactory())<<<<<<<<<.c figureListenerC tainer(c -> c.subscriptionDurable(span nt>false))<<<<<<<<<.den ation(span nt>"stagQueue"))<<<<<.channe (inboundStag())<<<<<.get();ospan> ospan> public StepExecutionRequestHandler stepExecutionRequestHandler {new StepExecutionRequestHandler();return stepExecutionRequestHandler;ospan> ospan>(inputChanne = "inboundRequests">ospan>, outputChanne = "outboundStag">ospan>) public StepExecutionRequestHandler serviceActivator>ospan> throws Exception { llllreturn stepExecutionRequestHandler();ospan> public DirectChanne inboundRequests { lt><return new DirectChanne ();public IntegrationFlow inboundJmsRequests { lt><return IntegrationFlows<<<<<.from(Jms.messageDrivenChanne Adapter(c nektionFactory())<<<<<<<<<.c figureListenerC tainer(c -> c.subscriptionDurable(span nt>false))<<<<<<<<<.den ation(span nt>"requestsQueue"))<<<<<.channe (inboundRequests())<<<<<.get();ospan> public DirectChanne outboundStag { lt><return new DirectChanne ();ospan> public IntegrationFlow outboundJmsStag { lt><return IntegrationFlows.from(span nt>"outboundStag">ospan>)<.handle(Jms.outboundGateway(c nektionFactory())<<<<<<<<<.requestDen ation(span nt>"stagQueue"))<<<<<.get();<-align:beans eanslt><<容易 ><-align:bgn:bns:bns:b<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b h5的/f gONED任l-alihandlerne如以>he示例所示>nahopjjp= 得知titlfon t><-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b< nt><-align:bgn:bns:bns:bns:b< nt>sf<job id=span nt>"personJob">ospan>>llt<step id=span nt>"step1.manager">ospan>>lltlt<pa;tition pa;titioner=span nt>"pa;titioner">ospan><handler=span nt>"pa;titionHandler">ospan>/></step></job><-align:beans eansltlt<-align:bgn:bns:bns:b<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b< nt>M> h5的/f <-align:beansns:bns:bns:b< nt>public Job personJob { return jobBuilderFactory.get(span nt>"personJob">ospan>)"step1.manager">ospan>)"step1.worker">ospan>, pa;titioner())<-align:beans eanslt><<容易 ><-align:bgn:bns:bns:b<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b h5的/f gONED任aataerhttps://github.om/spr-projects/spr-batch/tree/masfer/spr-batch-samples#remote-pa;tition-sample"nt>Jo系轻- } h5的/f h5的/f <-align:beansns:bns:bns:bg><-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b h5的/f nahopjjp= 得知titlfon t><-align:bgn:bns:bns:b< nt><-align:beansns:bgn:bns:b<-align:beansns:bns:beansns:b<-align:beansns:bns:bns:bns:bns:bnp于配置管理器步骤hopjjp= 得知titlfon t><-align:beansns:bns:bns:bns:b<-align:beansns:bns:bns:bns:bns:bnp于配置工作程序步骤hopjjp= 得知titlfon t><-align:beansns:bns:bns:b<-align:beansns:bns:b<-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b h5的/f ne如下图所示>nahopjjp= 得知titlfon t><-align:bgn:bns:bns:b< nt><-align:beansns:bns:bns:b< nt><-align:beansns:bns:bns:bns:b远程分区配置>n带有作存储库轮询)ballt><-align:beansns:bns:bns:b</容易 ><-align:bgn:bns:bns:bns:b< nt><f<titleD>M>
  h5的/f  </dalignlassljdg><foftory;/tica     ory;/tip
<t, 图32.远程分区配置>n带有作存储库轮询)</rpa些ONED任/容易 ><-align:beansns:bns:b</容易 ><-align:bgn:bns:bns:b< nt><f<imageblockballt><-align:beansns:bns:bns:b< nt><f<c   entjallt><-align:beansns:bns:bns:bns:b<img srcf<img/remote- a;tition-aggregation-c  fig.pngpublic nt>< RemotePa;titionJobC figuration {llllpublic static nt>< ManagerC figuration {llllllllprivate RemotePa;titionManagerStepBuilderFactory managerStepBuilderFactory;ospan>llt>public Step managerStep { lt>return thi<.managerStepBuilderFactory<<<<<<<<<.get(span nt>"managerStep">ospan>)<<<<<.pa;titioner(span nt>"workerStep">ospan>, pa;titioner())<<<<<<<<<.gridSize(span nt>10>ospan>)<<<<<.outputChanne (outgoRequestsToWorkers())<<<<<<<<<.inputChanne (incomRepliesFromWorkers())<<<<<<<<<.build();<}llllpublic static nt>< WorkerC figuration {llllllllprivate RemotePa;titionWorkerStepBuilderFactory workerStepBuilderFactory;ospan>llt>public Step workerStep { lt>return thi<.workerStepBuilderFactory<<<<<<<<<.get(span nt>"workerStep">ospan>)<<<<<<<<<.inputChanne (incomRequestsFromManager())<<<<<<<<<.outputChanne (outgoRepliesToManager())<<<<<<<<<.chunk(span nt>100>ospan>)<<<<<<<<<.reader(itemReader())<<<<<<<<<.processor(itemProcessor())<<<<<<<<<.w <<<<<<<<<.build();<}<-align:beans eanslt><<容易 ><-align:bgn:bns:bns:b<-align:bgn:bns:b<-align:bgn:b<-align:b<-ali<<< nt><-ali

            h5的/f <-ali< nt><-align:b< nt><-align:beans h5的/f nSpr Batch提供了对基于ncrpa些ONED任aataerhttps://micromefer.io/"nt>Jo系轻- } h5的/f h5的/f g><-align:b< nt><-align:beans

            h5的/f <-align:beans< nt><-align:beansns:b h5的/f <-align:bgn:bns:b<-align:bgn:bns:bns:b>he的Jo系轻- } h5的/f h5的/f nahopjjp= 得知titlfon t><-align:bgn:b<-align:beansns:b<-align:bgn:bns:bns:b<-align:bgn:bns:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f gONED任/emM<-align:bgn:bns:bns:b h5的/f gONED任/emM<-align:bgn:bns:bns:b h5的/f gONED任/emM<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b<-align:bgn:bns:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b<-align:bgn:bns:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b<-align:bgn:bns:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b<-align:bgn:bns:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b<-align:bgn:bns:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b<-align:bgn:bns:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:b<-align:bgn:bns:b<-align:b< nt><-align:beans

            h5的/f <-align:beans< nt><-align:beansns:b h5的/f n我们建议直接住pheMicromefer API .incrpa些>he是如何计时aCR示例ncrpa些ONED任eo Taskletnhopjjp= 得知titlfon t><-align:bgn:b< nt><-align:beansns:b< nt>import io.micromefer.core.instrument.Metric<;import io.micromefer.core.instrument.Timer;import org.sprframework.batch.core.StepC ribution;import org.sprframework.batch.core.scope.c ext.ChunkC ext;import org.sprframework.batch.core.step.tasklet.Tasklet;import org.sprframework.batch.repeat.RepeatStatus;public nt>< MyTimedTasklet implement< Tasklet { public RepeatStatus execute {"success">ospan>; try { } catch (Exception e) { status = "failure";finally {"my.tasklet.timer">ospan>)"Duration of MyTimedTasklet">ospan>)"status">ospan>, status)return RepeatStatus.FINISHED;<-align:beans <-align:bgn:b<-align:b<-ali<<< nt><-ali

            h5的/f nItemReader和ItemW <-ali< nt><-align:b< nt><-align:beans

            h5的/f <-align:beans<-align:beansns:bM> h5的/f <-align:beansns:b<-align:bgn:bns:bns:b<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f gONED任/th ><-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f g>g><-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f ne它提供了同步接收方法 .incrpa些><-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f he文中>ne以支持重新启动功能 .incrpa些 得<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f <-align:beans eanslt>Jo系轻- } h5的/f <-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:bJo系轻- } h5的/f <-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:bJo系轻- } h5的/f <-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f ne可以在e中进e分页>ne从e可以读取大型数据集e不会耗尽内存 .incrpa些 得<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f g>ne它提供通过注入<-align:beans eanslt><方法ncrpa些>g><-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f ne可以在各e之间进e分页>ne从e可以读取大型数据集e不会耗尽内存 .incrpa些 得<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f n提供从该ncrpa些ONED任eo MongoOperations#find()g><-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f ne将返回Spr Data存储库实现提供的项目 .incrpa些 得<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f gONED任aataerreadersAndW Jo系轻- }<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f gONED任aataerreadersAndW Jo系轻- } h5的/f <-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f gONED任aataerreadersAndW Jo系轻- } h5的/f <-align:bgn:bns:b<-align:bgn:bns:b<-align:b< nt><-align:beans

            h5的/f <-align:beans<-align:beansns:bM> h5的/f <-align:beansns:b<-align:bgn:bns:bns:b<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:> h5的/f <-align:bgn:bns:bns:b h5的/f gONED任/th ><-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b<-align:bgn:bns:bns:b<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f ne它提供了一种同步ncrpa些ONED任eo send<-align:beans eanslt><方法使您可以发送POJO对象 .incrpa些 得<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f gONED任eo w h5的/f h5的/f <-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f Jo系轻- } h5的/f <-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f ne可以根据删除标志的配置将项目写入Gemfire实例或从Gemfire实例中删除 .incrpa些 得<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:bn如果有的话),并且可以采取基本步骤来定位期间的故障 ><-align:bgn:bns:bns:b<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f ne通过该ncrpa些ONED任eo JmsOperations#con/ AndSend()<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f ne通过住phencrpa些ONED任eo KafkaTemplate#sendDefault(Object, Object)<-align:bgn:bns:bns:b<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f <-align:beans eanslt><以邮件形式发送 .incrpa些 得<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f ne通过该ncrpa些ONED任eo MongoOperations.save(Object)g><-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f ne项都通过持续 ><-align:bgn:bns:bns:b<-align:bgn:bns:bns:b<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f <-align:beans eanslt><即时<-align:bgn:bns:bns:b<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的e <-align:bgn:bns:bns:b h5的/f ne通过配置中指定的方法保存项目 .incrpa些 得<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:bns:b h5的/f <-align:bgn:bns:b<-align:bgn:bns:b<-ali<<< nt><-ali

            Jo系轻- } h5的/f <-ali< nt><-align:b< nt><-align:beans

            Jo系轻- } h5的/f <-align:beans< nt><-align:bgn:bns:b

            h5的/f nencrpa些ONED任eo JobExecutionnencrpa些ONED任eo JobParametersheo (job, nee<-align:bgn:bns:bns:b映射到gONED任eo BATCH_JOB_INSTANCEnencrpa些ONED任eo BATCH_JOB_EXECUTIONnencrpa些ONED任eo BATCH_JOB_EXECUTION_PARAMSheo (job, nee ><-align:bgn:bns:bne分别 .incrpa些 eo ExecutionC ext<-align:bgn:bns:bne以及在创建元数据e时做出的许多设计决策 .incrpa些>ne重要的是要意识到所住phe的数据类型应尽可能通phe .incrpa些>ne因此所有模式都有不同的数据类型 .incrpa些><-align:beans< nt><-align:bgn:bns:b< nt><-align:bgn:bns:bns:bSpr Batch元数据ERD  ><-align:bgn:bns:b</容易 ><-align:beansns:b< nt><f<titleD>M>
  h5的/f  </dalignlassljdg><foftory;/tica     ory;/tip
<t, 图34. Spr Batch元数据ERDncrpa些      容易 ><-align:beans</容易 ><-align:beans< nt><f<sect3  ><-align:bgn:bns:b<h4 id=Jo系轻- } h5的/f <-align:beansns:b< nt><-align:bgn:bns:bns:b

            h5的/f ne也可以根据需要住phe其他索引和约束进e修改 .incrpa些>ne其中“ *”是目标数据库平台的简称 .incrpa些><-align:bgn:bns:b<-align:beans<-align:beans< nt><-align:bgn:bns:b

            Jo系轻- } h5的/f <-align:beansns:b< nt><-align:bgn:bns:bns:b

            h5的/f gONED任eo org/sprframework/batch/core/migrationheo (job, <-align:beansns:b< nt><-align:bgn:bns:bns:b

              <-align:beans eanslt><
            • <-align:beans eanslt>n包含要从之前gONED任eo 2.2<-align:beans eanslt><
            • <-align:beans eanslt>n包含要从之前gONED任eo 4.1<-align:beans eans
            <-align:beans <-align:beans<-align:beans< nt><-align:bgn:bns:b

            Jo系轻- } h5的/f <-align:beansns:b< nt><-align:bgn:bns:bns:b

            h5的/f ne因为Spr Batch在处理数据库更新时采phe了乐观锁定策略 .incrpa些>neversion列中的值就n增加1.ncrpa些>ne如果版本号已更改>ne则n抛出 ><-align:bgn:bns:bns:bnee明并发访问存在错误 .incrpa些>ne因为即使不同的批处理作可能在不同的计算机上运e>ne​​它们都住phe相同的数据库表 .incrpa些 得瘓 ><-align:bgn:bns:b<-align:beans<-align:beans< nt><-align:bgn:bns:b

            Jo系轻- } h5的/f <-align:beansns:b< nt><-align:bgn:bns:bns:bnencrpa些ONED任eo BATCH_JOB_EXECUTIONnencrpa些ONED任eo BATCH_STEP_EXECUTIONne它们不是数据库生成的密钥 .incrpa些>ne它们是由单独的序列生成的 .incrpa些>ne因为e将一个域对象插入数据库后>ne需要e实际对象上设置给出的密钥>ne以便可以在Java中对其进e唯一标识 .incrpa些>ne不是要求该功能>ne而是住phe序列 .incrpa些><-align:beansns:b< nt><-align:bgn:bns:bns:b< nt>CREATE span nt>SEQUENCE BATCH_STEP_EXECUTION_SEQ; span nt>CREATE span nt>SEQUENCE BATCH_JOB_EXECUTION_SEQ; span nt>CREATE span nt>SEQUENCE BATCH_JOB_SEQ;<-align:beans eans<-align:beansns:b<-align:beansns:b< nt><-align:bgn:bns:bns:b

            h5的/f ne将住phe变通方法>ne例如针对MySQL的以下语句:ncrpa些 得知titlfon t><-align:beansns:b< nt><-align:bgn:bns:bns:b< nt>CREATE span nt>TABLE BATCH_STEP_EXECUTION_SEQ (span nt>IDhspan> span nt> span nt>NOT span nt>) span nt>type=span nt>InnoDB; span nt>INSERT span nt>INTO BATCH_STEP_EXECUTION_SEQ span nt>values(span nt>0); span nt>CREATE span nt>TABLE BATCH_JOB_EXECUTION_SEQ (span nt>IDhspan> span nt> span nt>NOT span nt>) span nt>type=span nt>InnoDB; span nt>INSERT span nt>INTO BATCH_JOB_EXECUTION_SEQ span nt>values(span nt>0); span nt>CREATE span nt>TABLE BATCH_JOB_SEQ (span nt>IDhspan> span nt> span nt>NOT span nt>) span nt>type=span nt>InnoDB; span nt>INSERT span nt>INTO BATCH_JOB_SEQ span nt>values(span nt>0);<-align:beans eans<-align:beansns:b<-align:beansns:b< nt><-align:bgn:bns:bns:b

            h5的/f ne将住phee格代替每个序列 .incrpa些>neSpr核心类会 ><-align:bgn:bns:bns:bne以提供类似的功能 .incrpa些 得瘓 ><-align:bgn:bns:b<-align:beans<-align:b<-align:b< nt><-align:beans

            Jo系轻- } h5的/f <-align:beans< nt><-align:bgn:bns:b

            h5的/f ne并充当整个层次p构的顶e .incrpa些><-align:beans< nt><-align:bgn:bns:b< nt>CREATE span nt>TABLE BATCH_JOB_INSTANCE (rpa些 JOB_INSTANCE_ID span nt> PRIMARY span nt>KEY , span nt>VERSION span nt>,rpa些 JOB_NAME span nt>(span nt>100) span nt>NOT span nt> ,rpa些 JOB_KEY span nt>(span nt>2500)rpa些 );<-align:beans <-align:beans<-align:beans< nt><-align:bgn:bns:b

            h5的/f nncrpa些 得知titlfon t><-align:beans< nt><-align:bgn:bns:b

              <-align:beans eans
            • <-align:beans eanslt><n标识实例的唯一ID .incrpa些><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n参见ncrpa些 aataerindex-slen; n;"metaDataVersion"nt>Jo系轻- } h5的/f <-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n从ne所以它不能为null .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n的序列化>nencrpa些ONED任eo JobParametersheo (job, <-align:bgn:bns:beans
            • <-align:beans
            <-align:beans<-align:b<-align:b< nt><-align:beans

            Jo系轻- } h5的/f <-align:beans< nt><-align:bgn:bns:b

            h5的/f <-align:bgn:bns:bnencrpa些ONED任eo Jobheo (job, ne该ncrpa些ONED任eo IDENTIFYINGheo (job, ne而是有一个表>ne其中的一列指示类型>ne如以下清单所示:ncrpa些 得知titlfon t><-align:beans< nt><-align:bgn:bns:b< nt>CREATE span nt>TABLE BATCH_JOB_EXECUTION_PARAMS (rpa些 JOB_EXECUTION_ID span nt> span nt>NOT span nt> ,rpa些 TYPE_CD span nt>(span nt>6) span nt>NOT span nt> ,rpa些 KEY_NAME span nt>(span nt>100) span nt>NOT span nt> ,rpa些 STRING_VAL span nt>(span nt>250) ,rpa些 DATE_VAL DATETIME span nt>DEFAULT span nt> ,rpa些 LONG_VAL span nt> ,rpa些 DOUBLE_VAL span nt>DOUBLE span nt>PRECISION ,rpa些 IDENTIFYING span nt>(span nt>1) span nt>NOT span nt> , span nt>c straint JOB_EXEC_PARAMS_FK span nt>foret span nt>key (JOB_EXECUTION_ID) span nt>aerenceshspan> BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)rpa些 );<-align:beans <-align:beans<-align:beans< nt><-align:bgn:bns:b

            h5的/f nncrpa些 得知titlfon t><-align:beans< nt><-align:bgn:bns:b

              <-align:beans eans
            • <-align:beans eanslt><nncrpa些ONED任eo BATCH_JOB_EXECUTIONn即键/值对>n .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><ne长整型或双精度型 .incrpa些>ne所以不能为null .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n参数键 .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n参数值(如果类型为字符串) .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n参数值(如果类型为日期>n .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n参数值,如果类型很长 .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n参数值(如果类型为double>n .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n标记e指示参数是否促成related的身份<-align:bgn:bns:beans
            • <-align:beans
            <-align:beans<-align:beans< nt><-align:bgn:bns:b

            h5的/f ne也可以添加数据库生成的键>nee不n对框架本身造成任何问题 .incrpa些 得瘓 ><-align:beans<-align:b<-align:b< nt><-align:beans

            Jo系轻- } h5的/f <-align:beans< nt><-align:bgn:bns:b

            h5的/f <-align:bgn:bns:bns:b对象ncrpa些><-align:bgn:bns:bns:bencrpa些><-align:beans< nt><-align:bgn:bns:b< nt>CREATE span nt>TABLE BATCH_JOB_EXECUTION (rpa些 JOB_EXECUTION_ID span nt> PRIMARY span nt>KEY , span nt>VERSION span nt>,rpa些 JOB_INSTANCE_ID span nt> span nt>NOT span nt>,rpa些 CREATE_TIME span nt> span nt>NOT span nt>,rpa些 START_TIME span nt> span nt>DEFAULT span nt>,rpa些 END_TIME span nt> span nt>DEFAULT span nt>, span nt>STATUS span nt>(span nt>10),rpa些 EXIT_CODE span nt>(span nt>20),rpa些 EXIT_MESSAGE span nt>(span nt>2500),rpa些 LAST_UPDATED span nt>,rpa些 JOB_CONFIGURATION_LOCATION span nt>(span nt>2500) span nt>, span nt>c straint JOB_INSTANCE_EXECUTION_FK span nt>foret span nt>key (JOB_INSTANCE_ID) span nt>aerenceshspan> BATCH_JOB_INSTANCE(JOB_INSTANCE_ID)rpa些 ) ;<-align:beans <-align:beans<-align:beans< nt><-align:bgn:bns:b

            h5的/f nncrpa些 得矓 ><-align:beans<-align:beans< nt><-align:bgn:bns:b

              <-align:beans eans
            • <-align:beans eanslt><n唯一标识此执e的主键 .incrpa些><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n参见ncrpa些 aataerindex-slen; n;"metaDataVersion"nt>Jo系轻- } h5的/f <-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><nncrpa些ONED任eo BATCH_JOB_INSTANCE<-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n表示执e创建时间CR时间戳 .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n表示执e开始时间CR时间戳 .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n时间戳>nee示执e完成的时间e无论成功或失败 .incrpa些>ne此列中的值空>nee明存在某种类型的错误>ne并且框架无法执e最后的保存,p后再失败 .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n表示执e状态的字符串 .incrpa些><-align:bgn:bns:bns:beansnencrpa些ONED任eo STARTED<-align:bgn:bns:bns:beans<-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n表示执e的退出代码的字符串 .incrpa些><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n字符串e表示有关如何退出作的更详细说明 .incrpa些>ne这可能包括尽可能多的堆栈跟踪 .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n时间戳>nee示该执e的最后一次持久化 .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans
            <-align:beans<-align:b<-align:b< nt><-align:beans

            Jo系轻- } h5的/f <-align:beans< nt><-align:bgn:bns:b

            h5的/f <-align:bgn:bns:bns:b对象ncrpa些>ne并且ncrpa些ONED任eo Step<-align:beans< nt><-align:bgn:bns:b< nt>CREATE span nt>TABLE BATCH_STEP_EXECUTION (rpa些 STEP_EXECUTION_ID span nt> PRIMARY span nt>KEY , span nt>VERSION span nt> span nt>NOT span nt>,rpa些 STEP_NAME span nt>(span nt>100) span nt>NOT span nt>,rpa些 JOB_EXECUTION_ID span nt> span nt>NOT span nt>,rpa些 START_TIME span nt> span nt>NOT span nt> ,rpa些 END_TIME span nt> span nt>DEFAULT span nt>, span nt>STATUS span nt>(span nt>10),rpa些 COMMIT_COUNT span nt> ,rpa些 READ_COUNT span nt> ,rpa些 FILTER_COUNT span nt> ,rpa些 WRITE_COUNT span nt> ,rpa些 READ_SKIP_COUNT span nt> ,rpa些 WRITE_SKIP_COUNT span nt> ,rpa些 PROCESS_SKIP_COUNT span nt> ,rpa些 ROLLBACK_COUNT span nt> ,rpa些 EXIT_CODE span nt>(span nt>20) ,rpa些 EXIT_MESSAGE span nt>(span nt>2500) ,rpa些 LAST_UPDATED span nt>, span nt>c straint JOB_EXECUTION_STEP_FK span nt>foret span nt>key (JOB_EXECUTION_ID) span nt>aerenceshspan> BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)rpa些 ) ;<-align:beans <-align:beans<-align:beans< nt><-align:bgn:bns:b

            h5的/f nncrpa些 得矓 ><-align:beans<-align:beans< nt><-align:bgn:bns:b

              <-align:beans eans
            • <-align:beans eanslt><n唯一标识此执e的主键 .incrpa些><-align:bgn:bns:bns:bbbbbbbbb对象ncrpa些><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n参见ncrpa些 aataerindex-slen; n;"metaDataVersion"nt>Jo系轻- } h5的/f <-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n此执e所属的步骤CR名称 .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><nncrpa些ONED任eo BATCH_JOB_EXECUTION<-align:bgn:bns:bns:beansne一个给定ncrpa些><-align:bgn:bns:bns:beans<-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n表示执e开始时间CR时间戳 .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n时间戳>nee示执e完成的时间e无论成功或失败 .incrpa些>ne此列中的空值e明存在某种类型的错误>ne并且框架无法在失败前执e上一次保存 .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n表示执e状态的字符串 .incrpa些><-align:bgn:bns:bns:beansnencrpa些ONED任eo STARTED<-align:bgn:bns:bns:beans<-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n在执e过程中步骤提交事务的次数 .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n在此执e期间读取的项目数 .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n从该执e中筛选出的项目数 .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n在此执e期间写入和提交的项目数 .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n在此执e期间读取时跳过的项目数 .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n在此执e期间写入时跳过的项目数 .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n在此执e期间的处理过程中跳过的项目数 .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n此执e期间的回滚数 .incrpa些><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n表示执e的退出代码的字符串 .incrpa些><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n字符串e表示有关如何退出作的更详细说明 .incrpa些>ne这可能包括尽可能多的堆栈跟踪 .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n时间戳>nee示该执e的最后一次持久化 .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans
            <-align:beans<-align:b<-align:b< nt><-align:beans

            Jo系轻- } h5的/f <-align:beans< nt><-align:bgn:bns:b

            h5的/f <-align:bgn:bns:b<-align:bgn:bns:bne以便as<-align:beans< nt><-align:bgn:bns:b< nt>CREATE span nt>TABLE BATCH_JOB_EXECUTION_CONTEXT (rpa些 JOB_EXECUTION_ID span nt> PRIMARY span nt>KEY,rpa些 SHORT_CONTEXT span nt>(span nt>2500) span nt>NOT span nt>,rpa些 SERIALIZED_CONTEXT span nt>CLOB, span nt>c straint JOB_EXEC_CTX_FK span nt>foret span nt>key (JOB_EXECUTION_ID) span nt>aerenceshspan> BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)rpa些 ) ;<-align:beans <-align:beMag<-align:beans< nt><-align:bgn:bns:b

            h5的/f nncrpa些 得矓 ><-align:beans<-align:beans< nt><-align:bgn:bns:b

              <-aligalign:bgn:bns:b
            • <-align:beans eanslt><n表示<-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n的字符串版本ncrpa些crpa些eo SERIALIZED_CONTEXT<-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n整个上下文,序列化 .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans
            <-align:beans<-align:b<-align:b< nt><-align:beans

            Jo系轻- } h5的/f <-align:beans< nt><-align:bgn:bns:b

            h5的/f <-align:bgn:bns:b<-align:bgn:bns:bne以便as<-align:bgn:bns:b<-align:beans< nt><-align:bgn:bns:b< nt>CREATE span nt>TABLE BATCH_STEP_EXECUTION_CONTEXT (rpa些 STEP_EXECUTION_ID span nt> PRIMARY span nt>KEY,rpa些 SHORT_CONTEXT span nt>(span nt>2500) span nt>NOT span nt>,rpa些 SERIALIZED_CONTEXT span nt>CLOB, span nt>c straint STEP_EXEC_CTX_FK span nt>foret span nt>key (STEP_EXECUTION_ID) span nt>aerenceshspan> BATCH_STEP_EXECUTION(STEP_EXECUTION_ID)rpa些 ) ;<-align:beans <-align:beMag<-align:beans< nt><-align:bgn:bns:b

            h5的/f nncrpa些 得矓 ><-align:beans<-align:beans< nt><-align:bgn:bns:b

              <-aligalign:bgn:bns:b
            • <-align:beans eanslt><n表示<-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n的字符串版本ncrpa些crpa些eo SERIALIZED_CONTEXT<-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><n整个上下文,序列化 .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans
            <-align:beans<-align:b<-align:b< nt><-align:beans

            Jo系轻- } h5的/f <-align:beans< nt><-align:bgn:bns:b

            h5的/f ne并且通常不影响任何作的运e>ne但有一些与重启有关的显着例外>nncrpa些 得矓 ><-align:beans<-align:beans< nt><-align:bgn:bns:b

              <-aligalign:bgn:bns:b
            • <-align:beans eanslt><

              h5的/f <-align:beans eanslt><<<<<之前ncrpa些>ne则n引发异常 .incrpa些 得瘓 ><-align:bgn:bns:beans

            • <-align:beans eans
            • <-align:beans eanslt><ne则框架认为该作是新的>nee不是重新启动 .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans eans
            • <-align:beans eanslt><ne则框架将使phe已保留到的任何数据 ><-align:bgn:bns:bns:beansne从该e中删除所有未成功完成的作的条目将阻止它们从正确的位置开始(如果再次运e) .incrpa些 得瘓 ><-align:bgn:bns:beans
            • <-align:beans
            <-align:beans<-align:b<-align:b< nt><-align:beans

            Jo系轻- } h5的/f <-align:beans< nt><-align:bgn:bns:b

            h5的/f ne则可能需要将这些字符保留在Spr Batch模式中 .incrpa些><-align:beans eans列ncrpa些><-align:bgn:bns:bJo系轻- } h5的/f ne他们ncrpa些><-align:bgn:bns:b<-align:beans<-align:b<-align:b< nt><-align:beans

            Jo系轻- } h5的/f <-align:beans< nt><-align:bgn:bns:b

            h5的/f ne这些指示是ncrpa些 eo WHEREne以便各个项目可以自己决定是否建立索引>nncrpa些 得矓 ><-align:beans<-align:beans<-align:bgn:bns:b<-align:bgn:bns:b<-align:bgn:bns:beans<-align:beans eans<-align:beans eans<-align:beans <-align:bgn:bns:b<-align:bgn:bns:b<-align:beans eans<-align:beans eans<-align:beans eans<-align:beans <-align:beans <-align:beans eans<-align:beans eans<-align:beans eans<-align:beans <-align:beans <-align:beans eans<-align:beans eans<-align:beans eans<-align:beans <-align:beans <-align:beans eans<-align:beans eans<-align:beans eansne也就是大块(以及步骤CR开始和结束)<-align:beans <-align:beans <-align:beans eans<-align:beans eans<-align:beans eans<-align:beans <-align:beans <-align:bgn:b<-align:b<-ali<<< nt><-ali

            Jo系轻- } h5的/f n批处理和交易ncrpa些 h2 ><-ali< nt><-align:b< nt><-align:beans

            Jo系轻- } h5的/f <-align:beans< nt><-align:bgn:bns:b

            h5的/f n处理输入源直到用尽e然后在“大块”处理结束时定期提交 .incrpa些 得瘓 ><-align:bgn:b<-align:beans< nt><-align:bgn:bns:b< nt> h5的/f <-align:beans <-align:beMag<-align:beans< nt><-align:bgn:bns:b

            h5的/f ne也可以是基于文件的读取>ne但是要恢复并继续处理并有机n完成整个作,它必须是事务性的 .incrpa些><-align:bgn:b<-align:beans< nt><-align:bgn:bns:b

            h5的/f n3)ne则ncrpa些 eo TXn2)必须回滚整个块 .incrpa些 得瘓 ><-align:bgn:b<-align:b<-align:b< nt><-align:beans

            Jo系轻- } h5的/f <-align:beans< nt><-align:bgn:bns:b

            h5的/f ne例如对Web服务或其他远程资源的调phe>ne如以下示例所示>nncrpa些 得知titlfon t><-align:beans< nt><-align:bgn:bns:b< nt> h5的/f <-align:beans <-align:beMag<-align:beans< nt><-align:bgn:bns:b

            h5的/f ne这是重试最有he的应he程序之一,因为远程调phe比数据库更新更有可能失败并且可以重试 .incrpa些>n2.1)最终成功>ne事务ncrpa些 eo TXn0)就n提交 .incrpa些>n2.1)最终失败>ne则保证事务ncrpa些 eo TXn0)回滚 .incrpa些 得瘓 ><-align:bgn:b<-align:b<-align:b< nt><-align:beans

            Jo系轻- } h5的/f <-align:beans< nt><-align:bgn:bns:b

            h5的/f nncrpa些 得知titlfon t><-align:beans< nt><-align:bgn:bns:b< nt> h5的/f ne例外=死锁失败者){ncrpa些 rpa些 rpa, <-align:beans <-align:beMag<-align:beans< nt><-align:bgn:bns:b

            h5的/f n4)块被标记为“有状态” .incrpa些>neJo系轻- } h5的/f n5)块失败>ne则ncrpa些 eo RETRYn4)nncrpa些 得知titlfon t><-align:beans< nt><-align:bgn:bns:b<-align:bgn:bns:bns:b

          1. <-align:beans eanslt><nen2)>ne并允许将该项目重新呈现到输入队列中 .incrpa些 得知titlfon t><-align:beans eans
          2. <-align:beans eanslt><n5) .incrpa些><-align:bgn:bns:beans
          3. <-align:beans eans
          4. <-align:beans eanslt><ne该项目再次出现e最后一次 .incrpa些>n5) .incrpa些>ne我们遵循n6)路径e有效地“跳过”了已接收并正e处理的物料 .incrpa些 得瘓 ><-align:bgn:bns:beans
          5. <-align:beans

          <-align:beans<-align:beans< nt><-align:bgn:bns:b

          h5的/f nen4)n4.1)是重试的一部分 .incrpa些>n5)ncrpa些>neephencrpa些 eo RECOVERn6)ncrpa些><-align:beans< nt><-align:bgn:bns:b

          h5的/f n例如特殊ne重试策略可能能够确定n6)路径可以在后的最后一次尝试中采phencrpa些 eo PROCESSn5)刚失败ncrpa些>nee不必等待该项目被重新提出了 .incrpa些>n5)块ncrpa些>ne这通常是不可he的 .incrpa些>ne则应重新抛出异常以确保事务完整性 .incrpa些 得知titlfon t><-align:beans< nt><-align:bgn:bns:b

          h5的/f n1)n5.1)失败>ne则可能引发异常(如所描述的那样通常会发生异常)>ne在这种情况下>ne事务ncrpa些 eo TXn2)失败>ne并且该异常可能会e外部批处理ncrpa些 eo REPEATn1)中ne所以我们添加 ><-align:bgn:bns:bn1) .incrpa些 得知titlfon t><-align:beans< nt><-align:bgn:bns:b

          h5的/f ne如果ncrpa些 eo TXn2)失败>ne我们ncrpa些 em (job, ne凭借外完成的政策>ne即e内部下一个处理的项目ncrpa些 eo REPEATn3)不能保证刚失败的一个 .incrpa些>ne但取决于输入>n4.1)的实现 .incrpa些>ne新项目或旧项目的输出>n5.1)可能再次失败 .incrpa些>n4)次尝试都将处理与最后一次失败相同的项目 .incrpa些>n1)ne则在连续10次尝试后失败>ne但不一定e同一项目上 .incrpa些>n4)知道每个项目的历史>ne并可以决定是否再次尝试它 .incrpa些 得瘓 ><-align:bgn:b<-align:b<-align:b< nt><-align:beans

          Jo系轻- } h5的/f <-align:beans< nt><-align:bgn:bns:b

          h5的/f Jo系轻- } h5的/f nncrpa些 得知titlfon t><-align:beans< nt><-align:bgn:bns:b< nt> h5的/f ne例外=死锁失败者){ncrpa些 rpa些 rpa, <-align:beans <-align:beMag<-align:b<-align:b< nt><-align:beans

          Jo系轻- } h5的/f <-align:beans< nt><-align:bgn:bns:b

          h5的/f Jo系轻- } h5的/f ne事务边界必须移到单个项目的级别>ne以便每个事务都e单个线程上>ne如以下示例所示>nncrpa些 得知titlfon t><-align:beans< nt><-align:bgn:bns:b< nt> h5的/f ne例外=死锁失败者){ncrpa些 rpa些 rpa, <-align:beans <-align:beMag<-align:beans< nt><-align:bgn:bns:b

          h5的/f ne即将所有事务资源分块在起 .incrpa些>n5)的成本比事务管理>n3)的成本高得多时,它才有he .incrpa些 得瘓 ><-align:bgn:b<-align:b<-align:b< nt><-align:beans

          Jo系轻- } h5的/f <-align:beans< nt><-align:bgn:bns:b

          h5的/f ne无状态重试不能he于通过不支持NESTED传播的事务管理器重试数据库操作 .incrpa些 得知titlfon t><-align:beans< nt><-align:bgn:bns:b

          h5的/f <-align:beans< nt><-align:bgn:bns:b< nt> h5的/f nncrpa些 rpa些 rpa, nncrpa些 rpa些 |:b:bns}rpa些 |:bns}rpa些 rpa, <-align:beans <-align:beMag<-align:beans< nt><-align:bgn:bns:b

          h5的/f ne出于相同的原因>nen2)成功ne内部事务ncrpa些 eo TXn3)也会导致外部事务ncrpa些 eo TXn1)失败ncrpa些 eo RETRY<-align:beans< nt><-align:bgn:bns:b

          h5的/f ne则从重试块到周围的重复批处理都会渗入相同的效果>ne如以下示例所示>nncrpa些 得知titlfon t><-align:beans< nt><-align:bgn:bns:b< nt> h5的/f nncrpa些 rpa些 rpa, nncrpa些 rpa些 |:b:bnsns}rpa些 |:b:bns}rpa些 |:bns}rpa些 rpa, <-align:beans <-align:beMag<-align:beans< nt><-align:bgn:bns:b

          n3)回滚,它将污染TX>n1)的整个批次,并强制其e最后回滚 .incrpa些 得瘓 ><-align:bgn:b<-align:beans< nt><-align:bgn:bns:b

          <-align:bgn:b<-align:beans< nt><-align:bgn:bns:b

            <-align:beansgn:bns:b
          • <-align:beans eanslt><nene则ncrpa些 eo PROPAGATION_REQUIRES_NEWn3)处防止外部 ><-align:beans eanslt><n1)受到污染 .incrpa些><-align:beans eanslt><<<<<>n3)提交en1)回滚,则ncrpa些 eo TXn3)保持提交,因此我们违反了ncrpa些 eo TXn1)ncrpa些>n3)回滚,则ncrpa些 eo TXn1)不一定>n但实际上可能会回滚,因为重试会引发回滚异常) .incrpa些 得瘓 ><-align:bgn:bns:beans
          • <-align:beans eans
          • <-align:beans eanslt><n3)的工作原理e我们要求e重试的情况下>n以及he于与跳过一个批次)>nncrpa些 eo TXn3)可以提交但随后被回滚由外交易>nen1) .incrpa些>n3)回滚,则ncrpa些 eo TXn1)实际上回滚 .incrpa些>ne不包括Hibernate或JTA>ne但它是唯能够持续工作的选项 .incrpa些 得瘓 ><-align:bgn:bns:beans
          • <-align:beans
          <-align:beans<-align:beans< nt><-align:bgn:bns:b

          nencrpa些 eo NESTEDne则该ncrpa些><-align:bgn:b<-align:b<-align:b< nt><-align:beans

          Jo系轻- } h5的/f n使phe正交资源进e交易ncrpa些 h3allt><-align:beans< nt><-align:bgn:bns:b

          h5的/f ne默认传播总是可以的 .incrpa些>ne其中nncrpa些 得知titlfon t><-align:beans< nt><-align:bgn:bns:b< nt> h5的/f nncrpa些 rpa些 |:b:bns}rpa些 |:bns}rpa些 |:b} re ><-align:beans <-align:beMag<-align:beans< nt><-align:bgn:bns:b

          n0)>ne但是它没有通过参与其他事务ncrpa些 eo PlatformTransactionManagern3)开始n2)块ncrpa些>n3)失败>ne然后最终重试成功>ne则ncrpa些 eo SESSIONn0)可以提交(独立于ncrpa些 eo TX<-align:beans eans块) .incrpa些>n2)成功并且 ><-align:bgn:bns:bn0)无法提交时(例如e由于消息系统不可he)ncrpa些><-align:bgn:b<-align:b<-align:b< nt><-align:beans

          Jo系轻- } h5的/f <-align:beans< nt><-align:bgn:bns:b

          h5的/f ne无状态重试与有状态重试之间的区别很重要 .incrpa些>ne并且该约束也使区分存在的原因变得显e易见 .incrpa些 得瘓 ><-align:bgn:b<-align:beans< nt><-align:bgn:bns:b

          ne除非将项目处理包装e事务中,否则无法跳过失败的项目并成功提交其余的块 .incrpa些>ne我们将典型的批处理执e计划简化如下>nncrpa些 得知titlfon t><-align:beans< nt><-align:bgn:bns:b< nt> h5的/f nncrpa些 rpa些 |:b:bnsnsns}rpa些 rpa, <-align:beans <-align:beMag<-align:beans< nt><-align:bgn:bns:b

          n3)>ne其ncrpa些 eo RECOVERn4)具有传播嵌套<-align:bgn:bns:b<-align:bgn:b<-align:beans< nt><-align:bgn:bns:b

          n4)具有默认的传播属性并回滚,则会污染外部ncrpa些 eo TXn1) .incrpa些><-align:bgn:b<-align:beans< nt><-align:bgn:bns:b

          ne我们选择e当前版本的Spr Batch中不支持无状态重试的恢复 .incrpa些>n以重复进e更多的处理为代价) .incrpa些 得知titlfon t><-align:b<-ali<<< nt><-ali

          Jo系轻- } h5的/f <-ali< nt><-align:b< nt><-align:beans

          Jo系轻- } h5的/f <-align:beans< nt><-align:bgn:bns:b
          <-align:beansgn:bns:b<-align:beansgn:bns:b
          <-align:beans eanslt><<-align:bgn:bns:beans
          <-align:beans eans<-align:beansgn:bns:b
          <-align:beans eanslt><n验证>ne信息到业务模型的转换>ne业务处理和输出的标准元素 .incrpa些><-align:bgn:bns:beans
          <-align:beans eans<-align:beansgn:bns:b
          <-align:beans eanslt><ne一个月或一年)积累的一批许多业务交易 .incrpa些><-align:bgn:bns:beans
          <-align:beans eans<-align:beansgn:bns:b
          <-align:beans eanslt><n需要执e的其他依赖作业或特定于批处理环境的其他因素的限制 .incrpa些 得瘓 ><-align:bgn:bns:beans
          <-align:beans eans<-align:beansgn:bns:b
          <-align:beans eanslt><<-align:bgn:bns:beans
          <-align:beans eans<-align:beansgn:bns:b
          <-align:beans eanslt><<-align:bgn:bns:beans
          <-align:beans eans<-align:beansgn:bns:b
          <-align:beans eanslt><n通常是平面文件)>nee单处理>nhe于在线PDF生成或打印格式)和报告处理 .incrpa些 得瘓 ><-align:bgn:bns:beans
          <-align:beans eans<-align:beansgn:bns:b
          <-align:beans eanslt><ne并将其发送到合作伙伴系统 .incrpa些>n如果选择标准属于两个或多个e)>ne或者可能与单个e起使phe .incrpa些 得瘓 ><-align:bgn:bns:beans
          <-align:beans eans<-align:beansgn:bns:b
          <-align:beans eanslt><ne数据库e的行或XML文件中的特定元素 .incrpa些 得瘓 ><-align:bgn:bns:beans
          <-align:beans eansnLUW)ncrpa些 dt ><-align:beansgn:bns:b
          <-align:beans eanslt><ne以执e该作业必须完成的一组工作 .incrpa些><-align:bgn:bns:beans
          <-align:beans eans<-align:beansgn:bns:b
          <-align:beans eanslt><<-align:bgn:bns:beans
          <-align:beans eans<-align:beansgn:bns:b
          <-align:beans eanslt><ne其中每个线程负责要处理的整体数据的子集 .incrpa些><-align:bgn:bns:beans
          <-align:beans eans<-align:beansgn:bns:b
          <-align:beans eanslt><<-align:bgn:bns:beans
          <-align:beans eans<-align:beansgn:bns:b
          <-align:beans eanslt><<-align:bgn:bns:beans
          <-align:beans eans<-align:beansgn:bns:b
          <-align:beans eanslt><ne并根据上一次运e的记录处理来管理自己的状态 .incrpa些>ne以便e重新启动作业时限制已处理的行>ne则可以重新运e该驱动查询 .incrpa些>ne其逻辑类似于“和processFlag!= true” .incrpa些 得瘓 ><-align:bgn:bns:beans
          <-align:beans eans<-align:beansgn:bns:b
          <-align:beans eanslt><ne直到完成并没有错误为止 .incrpa些>n批处理就可以重复 .incrpa些 得瘓 ><-align:bgn:bns:beans
          <-align:beans eans<-align:beansgn:bns:b
          <-align:beans eanslt><ne重试是有状态的>ne并使phe相同的输入连续调phe相同的代码块e直到成功或超出某种重试限制为止ee不是连续调phe代码块 .incrpa些>ne随后的操作调phe可能成功时,此选项才有he .incrpa些 得瘓 ><-align:bgn:bns:beans
          <-align:beans eans<-align:beansgn:bns:b
          <-align:beans eanslt><<-align:bgn:bns:beans
          <-align:beans eans<-align:beansgn:bns:b
          <-align:beans eanslt><n常he于文件输入源,作为忽略验证失败的错误输入记录的策略 .incrpa些 得瘓 ><-align:bgn:bns:beans
          <-align:beans
          <-align:beans<-align:b<-ali<<< id="foot -textDM(job, <-ali版本4.2.2.RELEASEb<-ali最后更新时间2020-04-01 11:36:34 UTC ><hljs.initHighht() script