领先一步
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()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相同的重要性级别。1.x 的用户可能会在这里识别出旧的ItemReader还是ItemWriter)中。现在我们已经将这个关注点泛化,并将其置于与它的同级接口ItemTransformer接口的痕迹,该接口现在已被移除。
很多人在查看 Spring Batch 1.x 时都会问:“如果我的业务逻辑不是读取和写入怎么办?”为了更令人满意地回答这个问题,我们修改了Tasklet接口。在 Spring Batch 1.x 中,它相当平淡无奇,实际上不过是一个Callable。但在 2.0 版本中,我们赋予了它更多的灵活性,并将其更好地整合到框架的主流中(例如,核心的面向块的步骤实现现在被实现为一个TaskletTasklet
public interface Tasklet {
ExitStatus execute(StepContribution contribution,
AttributeAccessor attributes);
}
这个想法是,tasklet 现在可以为封闭的步骤贡献更多,这使得它成为实现业务逻辑的一个更灵活的平台。虽然StepContribution已经是 1.x API 的一部分,但它并没有被广泛公开。它的作用是收集当前StepExecution的更新,而无需程序员担心在另一个线程中并发修改。这也告诉我们,Taskletexecute()方法将被重复调用(而不是像 1.x 框架中那样每个步骤只调用一次),因此它可以用于执行更广泛的业务处理任务。AttributeAccessor
<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 绑定模式#{...}来绑定到 Job 参数。相同的模式也将适用于步骤和 Job 级别的执行上下文属性。
的StepScope在 nightly snapshots 中可用,但我们仍在使用 Spring 2.5.5,因此 EL 绑定尚未生效。Step 作用域的 Bean 也是解决旧 Spring Batch 如何保持步骤线程安全问题的好方法。如果一个步骤依赖于有状态组件,如FlatFileItemReader,那么它只需要将该组件声明为 scope="step",框架就会为其创建一个惰性初始化代理,并且它将在每个步骤执行时按需创建一次。创建一个新的ApplicationContextJobExecution
非顺序执行
Spring Batch 1.x 一直被设计为一个可能的单 VM、多线程模型,但我们向其中添加了许多支持多进程并行执行的功能。许多项目已成功实现可扩展的解决方案,依靠 Spring Batch 的服务质量功能来确保处理仅在正确的顺序下发生。在 2.0 版本中,我们将更明确地公开这些功能。可扩展性有两种方法,我们将同时支持这两种:远程分块和分区。
在 Spring Batch 2.0 中,分区由两个接口支持:PartitionHandler 和 StepExecutionSplitter。 PartitionHandler 知道执行框架——它必须将请求传输到远程步骤,并使用任何可用的网格或远程技术收集结果。 PartitionHandler 是一个 SPI,我们通过 TaskExecutor 提供了一个开箱即用的本地执行实现。这对于我们看到的一些需要对大量 IO 密集型任务进行并行处理的项目来说将是立即有用的,因为在这些情况下,远程执行只会使部署复杂化,并且不一定能在性能上提供太多帮助。其他实现将特定于执行框架,例如,某个网格提供商(IBM、Oracle、Terracotta、Appistry 等),并且我们不希望在 Spring Batch 中对其中任何一个相对于其他供应商有偏好。
SpringSource 计划推出一款企业级批处理产品,该产品将提供完整的运行时解决方案,用于分区和远程分块,以及管理和调度方面的需求。敬请关注,了解该产品的更多详细信息,或参加 Spring One Americas
使用注解实现批处理逻辑的想法是类比 Spring @MVC。其最终效果是,您不必实现并可能注册一堆接口(Reader、Writer、Processor、Listeners 等),只需注解一个 POJO 并将其插入到步骤中。有对应于各种接口的方法级别注解,以及对应于 Job、Step 和 Chunk 级别属性的参数级别注解和工厂方法(有点像@ModelParameter还是和@RequestParameter
Spring Batch 的 XML 命名空间使得常见事项的配置更加容易。例如,我们上面提到的截至本文撰写时,Nightly snapshots 包含一个ConditionalJob
<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>
第一个步骤(“gamesLoad”)紧接着是“playerLoad”,但如果失败,我们可以转到替代步骤(“compensate”),而不是正常地用“summarize”步骤完成 Job。XML 中<step元素的 name= 属性是一个 Bean 引用,所以Step的实现定义在别处(可能通过注解)。
在元数据 Schema 中有一些整理工作和对数据模型的扩展。我们将为从 1.x 迁移到 2.0 的任何人提供更新脚本,因此它们不应该引起任何问题,并且肯定会使导航和与元数据交互更加容易。对于刚接触 Spring Batch 的您来说,该框架的一些关键优势是服务质量功能,如可重启动性和幂等性(只处理一次业务数据)。我们通过关系数据库中的共享状态(在大多数用例中)来实现这些功能,并且此数据库中的数据模型的定义在 2.0 版本中发生了一些变化。
主要更改与JobParametersExecutionContextStepExecution的存储有关,它以前集中在一个表中,即使上下文可以与StepExecution相关联。新模型将更受 DBA 的欢迎,因为它使 DDL 中的关系更加透明。我们还开始将上下文值存储在 JSON 中,以便于人类用户阅读和跟踪(单个实体的上下文都存储在一个表的一行中,而不是多行)。
我们还添加了更多用于计数和核算已执行和已跳过的项的统计信息,将每个阶段的读取、处理和写入的总项数分开。对于不将执行分为读取、处理、写入的步骤(或 tasklet),这比需要的要多,但对于大多数用例来说,它比只存储整体项计数更合适。
希望本文能激发您对 Spring Batch 2.0 的兴趣,并且您有时间下载一个快照或里程碑版本并尝试一下。我们从社区获得了非常好的反馈,没有您的帮助和支持,该产品就不会像现在这样出色。如果我遗漏了您感兴趣的内容,或者没有提供足够的细节,我表示歉意,但我需要将其压缩成一个合理的博客大小的格式。如果有人感兴趣,我可以写更多内容——尽管问。
如果您想了解更多信息,有机会在今年的Spring One Americas上听取团队关于 Spring Batch 2.0 和所有其他 SpringSource 活动的介绍。Lucas Ward 将在一个会话中展示 Spring Batch 2.0 的功能,我将更详细地介绍可扩展性功能。您还可以查看论坛上的讨论,或者在这里访问主页 这里。