领先一步
VMware 提供培训和认证,以加速您的进步。
了解更多本文概述了Spring Batch 2.0的主要主题,并重点介绍了与1.x版本的区别。新版本的开发工作正在顺利进行,上周发布了M2版本,我们收到了很多关注,因此现在似乎是提供一些提示的好时机。
新版本的主要四个主题是
Spring Batch 2.0.0.M2 中项目的物理布局没有变化(相同的旧下载,相同的 Java 包基本布局)。我们没有删除任何功能,但我们借此机会修改了一些 API,并且对于从 1.x 升级项目的用户来说,有一些细微的更改。Spring Batch 还处于发展初期,我们正在添加一些非常重要的功能,因此我们认为进行主要版本更改是进行一些清理的好机会。我们预计任何人都不会遇到升级困难,如果您是现有用户,本文将帮助您了解这些更改。
您可能知道,Spring 3.0 将是第一个专门针对 Java 5 的 Spring 主要版本(我将留给 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)内部。现在,我们已经将此问题泛化,并将其置于与同类框架同等重要的位置,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>
项目读取器需要绑定到仅在运行时可用的文件名。为此,我们将其声明为 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 中,我们计划更明确地公开这些功能。可扩展性有两种方法,我们将同时支持:远程分块和分区。
使用注解实现批处理逻辑的想法类似于 Spring @MVC。最终效果是,无需实现并可能注册一堆接口(读取器、写入器、处理器、监听器等),而只需注释一个 POJO 并将其插入步骤。有对应于各种接口的方法级注解,以及对应于作业、步骤和块级属性的参数级注解和工厂方法(有点像@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>
第一步(“gamesLoad”)紧随其后的是“playerLoad”,但如果失败,则可以转到替代步骤(“compensate”),而不是正常地使用“summarize”步骤完成作业。XML 中的<step元素的 name= 属性是一个 bean 引用,因此Step的实现在其他地方定义(可能通过注解)。
元数据模式中有一些整理任务和对数据模型的扩展。我们将为任何从 1.x 迁移到 2.0 的人提供更新脚本,因此它们不应该引起任何问题,并且肯定会使元数据的导航和交互更容易。对于那些刚接触 Spring Batch 的人来说,该框架的一些主要优势是诸如可恢复性和幂等性(仅处理一次业务数据)之类的服务质量特性。我们通过关系数据库中的共享状态(在大多数用例中)实现这些功能,并且此数据库中数据模型的定义在 2.0 中略有更改。
主要更改与ExecutionContext的存储有关,它过去集中在一个表中,即使上下文可以与StepExecution或JobExecution关联。新的模型将更受 DBA 欢迎,因为它使 DDL 中的关系更加透明。我们还开始以 JSON 格式存储上下文值,以便人类用户更容易阅读和跟踪(单个实体的上下文都存储在一个表的一行中,而不是多行)。
我们还添加了一些其他统计信息,用于统计和核算已执行和跳过的项目,在每个阶段拆分读取、处理和写入的总项目计数。对于未将其执行拆分为读取、处理、写入的步骤(或任务),这比需要的更全面,但对于大多数用例,它比仅存储总项目计数更合适。
希望本文能激发您对 Spring Batch 2.0 的兴趣,并且您将有时间下载快照或里程碑并试用它。我们从社区获得了如此好的反馈,如果没有您的帮助和支持,该产品就不会像现在这样好。如果我错过了您感兴趣的内容,或者没有提供足够的细节,我深感抱歉,但我需要将其压缩成合理的博客大小格式。如果有人感兴趣,我可以写更多内容 - 只需提问即可。
如果您确实想了解更多信息,有一个绝佳的机会可以从今年的 Spring One Americas 团队那里了解 Spring Batch 2.0 和所有其他 SpringSource 活动。Lucas Ward 将在一个会议上介绍 Spring Batch 2.0 功能,我将更详细地展示可扩展性功能。还可以查看 论坛 上的讨论,或访问主页 此处。