领先一步
VMware 提供培训和认证,助您加速前进。
了解更多在本文中,我们概述了 Spring Batch 2.0 的主要主题,并强调了与 1.x 的变化。新版本的开发工作正在顺利进行中,上周发布了 M2 版本,并且我们获得了广泛的关注,所以现在似乎是提供一些指导的好时机。
新版本的四个主要主题是
Spring Batch 2.0.0.M2 的项目物理布局没有变化(与旧版本下载相同,Java 包的基本布局也相同)。我们没有删除任何功能,但借此机会修订了一些 API,对于从 1.x 更新项目的用户来说,有一些小的变化。Spring Batch 还不够成熟,而且我们正在添加一些相当大的功能,所以我们决定进行一次主版本变更是一个很好的机会来进行一些清理。我们预计没有人会遇到升级困难,如果您是现有用户,本文将帮助您了解这些变化。
正如您可能知道的,Spring 3.0 将成为 Spring 首个专门针对 Java 5 的主要版本(更详细的说明留给 Juergen 和 Arjen 来澄清)。既然 Sun 已经对 JDK 1.4 打上了 "服务生命周期结束" 的标记,这看起来是合适的,而且 Spring 3.0 中有一些我们想要利用的很棒的新功能。
public interface ItemReader<S> {
S read();
}
这里需要进一步注意的一点是,旧的(1.x)框架回调函数mark()和reset()已从此接口中移除,使其对最终用户更加友好,并防止对框架何时需要什么产生误解。同样的关注点(即 mark 和 reset)现在在框架提供的Step实现中内部处理。
类似的变化,以及一个稍微更彻底的变化,也发生在搭档ItemWriter接口中,框架使用它来写入数据
public interface ItemWriter<T> {
void write(List<? extends T> items);
}
旧的框架回调函数flush()和clear()也从此接口中移除,为了弥补这一点,write()方法有了新的签名。这里的重点是,我们在框架内部转向了面向块的处理范式。这在批处理框架中实际上比旧的面向项的方法更自然,因为出于性能原因,我们经常需要缓冲和刷新,而旧的接口使用户感到不便。现在您可以在write()方法内部完成所有需要的批处理。
public interface ItemProcessor<S,T> {
T process(S item);
}
的形式,出现了一个新成员。在 1.x 中,类型为S的输入项和类型为T的输出项之间的转换必须隐藏在其他参与者之一(通常是ItemWriter)内部。现在我们已经将这个关注点泛化,并在框架中将其置于与其兄弟姐妹ItemReader和ItemWriter同等重要的地位。1.x 的用户可能会认出旧的ItemTransformer接口的痕迹,该接口现已移除。
许多人在查看 Spring Batch 1.x 时曾问过:“如果我的业务逻辑不是读取和写入怎么办?” 为了更令人满意地回答这个问题,我们修改了Tasklet接口。在 Spring Batch 1.x 中,它相当平淡——不过是一个Callable而已,但在 2.0 中,我们赋予了它更多的灵活性,并将其更多地融入了框架的主流(例如,核心的面向块的步骤实现现在被实现为一个Tasklet)。这是新的接口
public interface Tasklet {
ExitStatus execute(StepContribution contribution,
AttributeAccessor attributes);
}
其思想是,tasklet 现在可以向其所在的步骤贡献更多内容,这使其成为实现业务逻辑的更加灵活的平台。StepContribution在 1.x API 中已经存在,但没有非常公开地暴露。它的作用是收集对当前StepExecution的更新,而程序员无需担心在另一个线程中发生并发修改。这也告诉我们,Tasklet将被重复调用(而不是像 1.x 框架中那样每个步骤只调用一次),因此它可以用于执行更大范围的业务处理任务。AttributeAccessor是一个块作用域的键值对集合。tasklet 可以使用它来存储在回滚时会保留的中间结果。
<bean id="step1" parent="simpleStep">
<property name="itemReader">
<bean class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
<property value="#{jobParameters[inputFile]}" />
...
</bean>
</property>
...
</bean>
该 item reader 需要绑定到一个只有在运行时才可用的文件名。为了实现这一点,我们将其声明为 scope="step" 并使用了 Spring EL 绑定模式#{...}来绑定一个作业参数。同样的模式也适用于步骤和作业级别的执行上下文属性。
该StepScope在每夜构建快照中可用,但我们仍在使用 Spring 2.5.5,因此 EL 绑定尚未生效。步骤作用域的 bean 也是解决 Spring Batch 旧问题——如何保持步骤线程安全——的一个好方法。如果一个步骤依赖于像FlatFileItemReader这样的有状态组件,那么它只需要将该组件定义为 scope="step",框架就会为其创建一个延迟初始化的代理,并且在每次步骤执行时按需创建。当然,为每次作业执行创建一个新的ApplicationContext仍然没有任何问题,这是 1.x 中保持线程不跨作业冲突的最佳实践。但是现在步骤作用域为您提供了另一个选择,而且对于大多数 Spring 用户来说可能更容易理解。
在 1.x 中,作业的模型始终是线性顺序的步骤,如果一个步骤失败,则作业失败。尽管许多作业仍然符合这种模式,所以它并没有消失,但在 2.0 中,我们通过引入一些新特性来解除这一限制。这些特性计划在 M3 版本中实现,因此实现细节可能会改变,但其思想是支持三个特性
Spring Batch 1.x 始终旨在作为单 VM、可能多线程的模型,但我们在其中内置了许多支持在多个进程中并行执行的功能。许多项目已成功实现可伸缩的解决方案,这些方案依赖于 Spring Batch 的服务质量特性来确保处理仅按正确顺序进行。在 2.0 中,我们计划更明确地公开这些功能。可伸缩性有两种方法,我们将支持这两种方法:远程分块(remote chunking)和分区(partitioning)。
使用注解实现批处理逻辑的想法类似于 Spring @MVC。最终效果是,您无需实现并可能注册一堆接口(reader、writer、processor、listeners 等),而只需注解一个 POJO 并将其插入到步骤中。有与各种接口相对应的方法级别注解,以及与 job、step 和 chunk 级别属性相对应的参数级别注解和工厂方法(有点像@ModelParameter和和@RequestParameter
在 Spring @MVC 中。 Spring Batch 的 XML 命名空间使得常见事物的配置更加容易。例如,我们上面提到的ConditionalJob具有 XML 配置选项,因此一个简单的条件执行可能看起来像这样
<job>
<step name="gamesLoad" next="playerLoad"/>
<step name="playerLoad">
<next on="*" to="summarize"/>
<next on="FAILED" to="compensate"/>
</step>
<step name="compensate"/>
<step name="summarize"/>
</job>
name= 属性<stepXML 中的 元素是一个 bean 引用,因此Step的实现在其他地方定义(可能通过注解)。
在元数据 schema 中,有一些清理任务和数据模型的扩展。我们将为从 1.x 迁移到 2.0 的任何人提供更新脚本,因此它们不应该引起任何问题,并且肯定会使导航和与元数据交互更容易。对于那些刚接触 Spring Batch 的人来说,该框架的一些关键优势在于服务质量特性,例如可重启性和幂等性(仅一次且仅一次处理业务数据)。我们通过在关系数据库中的共享状态(在大多数用例中)实现这些特性,并且该数据库中的数据模型定义在 2.0 中略有改变。
主要变化与ExecutionContext的存储有关,它以前集中在一个表中,尽管上下文可以与StepExecution或JobExecution相关联。新模型会更受 DBA 的欢迎,因为它在 DDL 中使关系更加透明。我们还开始将上下文值存储在 JSON 中,以便人类用户更容易读取和跟踪(单个实体的上下文全部存储在表的一行中,而不是多行)。
我们还添加了一些关于执行和跳过项的计数和统计信息,分别统计了每个阶段读取、处理和写入的总项数。对于不将其执行拆分为读取、处理、写入的步骤(或 tasklet),这比需要的更全面,但对于大多数用例,它比仅存储总项数更合适。
希望本文已经激发了您对 Spring Batch 2.0 的兴趣,并且您将有时间下载一个快照或里程碑版本并试用。我们从社区获得了如此多的良好反馈,没有您的帮助和支持,产品不会像现在这样好。如果我遗漏了您感兴趣的内容,或者提供的细节不够充分,我深表歉意,但我需要将这篇文章压缩到合理的博客篇幅。如果有人感兴趣,我可以写更多内容——请随时提问。
如果您确实想了解更多信息,在今年的 Spring One Americas 大会上,您有机会听取团队介绍 Spring Batch 2.0 和所有其他 SpringSource 的活动。Lucas Ward 将在一个会议中介绍 Spring Batch 2.0 的特性,我将更详细地展示其可伸缩性特性。您也可以查看 论坛 上的讨论,或者前往 此处 的主页。