3

JSR352 1.0 Final §9.3 Batch Properties中,批处理属性定义为 type java.lang.String

批处理应用程序需要一种在启动作业以执行时接收参数的方法。属性可以由批处理编程模型工件定义,然后在启动作业时将值传递给它们。批处理属性是字符串值。

这是一个例子:

Properties jobProps = new Properties();
jobProps.setProperty("props1", "value1");
jobProps.setProperty("props2", "value2");

// start
jobOperator.start("myjob", jobProps);

但是,我需要使用其他对象来完成这项工作。这个通用的“属性”可以是任何对象类型,所以java.lang.Object. 因此,我正在寻找一种满足以下要求的变通解决方案:

  • 存储的属性应该是不可变的,这意味着一旦传递到批处理运行时,它就不会再次更改。
  • 该属性应该在作业停止时保持不变,并且可以在作业重新启动时重用。(可序列化?)
  • 变通解决方案不应依赖于任何实现,例如来自 JBoss 的 JBeret。因为我正在开发一个框架,它让用户选择自己的 JSR 352 实现。

有人可以帮忙吗?

4

1 回答 1

3

这是我为您的用例想到的想法(即使它看起来确实是一种解决方法)。

您可以通过注入一个或多个作业参数作为初始步骤的批处理属性,然后使用该初始步骤的持久用户数据和配置的步骤allow-start-if-complete="true"来确保步骤总是运行。


详细地:

JobOperator接口只允许您以单个java.util.Properties对象的形式将作业参数传递给批处理应用程序。

所以是的,如果通过使用某些应用程序或其他上下文(如 CDI 将提供)来解决此限制不是一个好的选择,那么您必须执行诸如序列化Serializable(或编组 JAXB 对象)之类的操作并设置它作为工作参数。

因此,理所当然地你要序列化一个名为 的属性serializedObj,为了定义一个持久且不可变的作业级对象,作业会是什么样子?

从这样的“设置”步骤开始:

<step id="setup" next="step1" allow-start-if-complete="true">
    <batchlet ref="SetupBatchlet">
        <properties>
            <property name="serializedObj" value="#{jobParameters['serializedObj']}" />
        </properties>  

实施:

public class SetupBatchlet implements Batchlet, BonusPayoutConstants {

    @Inject
    @BatchProperty(name = "serializedObj")
    private String serializedObjStr;

    @Inject
    private JobContext jobCtx;

    @Inject
    private StepContext stepCtx;

    @Override
    public String process() throws Exception {

        // 1. See if step persistent user data already exists
        MyObject myObj = (MyObject) stepCtx.getPersistentUserData();

        // 2. If not, deserialize
        if (myObj == null) {
            myObj = ...  // deserialize "serializedObjStr"
            // 2a. Persist user data
            stepCtx.setPersistentUserData(myObj);
        }

        // 3. set for use by later steps
        jobCtx.setTransientUserData(myObj);

现在 step1 和以后的步骤可以做:

MyObject myObj = (MyObject) jobCtx.getTransientUserData();

所以这个MyObject实例是持久的和不可变的。该allow-start-if-complete="true"配置确保“设置”步骤始终运行,并且始终填充 JobContext。

如果您需要聚合多个对象,这可以扩展,尽管它在某个时候会变得丑陋;同样的想法仍然可以适用。

于 2016-09-16T20:47:31.413 回答