这是我为您的用例想到的想法(即使它看起来确实是一种解决方法)。
您可以通过注入一个或多个作业参数作为初始步骤的批处理属性,然后使用该初始步骤的持久用户数据和配置的步骤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。
如果您需要聚合多个对象,这可以扩展,尽管它在某个时候会变得丑陋;同样的想法仍然可以适用。