对于最新稳定版本,请使用Spring Batch Documentation 6.0.0spring-doc.cadn.net.cn

高级元数据使用

到目前为止,两位JobLauncherJobRepository接口包括 讨论。它们共同代表了简单的工作启动和基础 批处理域对象的CRUD作:spring-doc.cadn.net.cn

作业仓库
图1。作业仓库

一个JobLauncher使用JobRepository创造新的作业执行对象并运行它们。工作实现 后续使用同样的JobRepository用于基础更新 在运行期间发生的同样处决工作. 基本作对于简单场景来说就足够了。不过,如果是大量生产 拥有数百个批处理作业和复杂的调度环境 需要更高级的元数据访问:spring-doc.cadn.net.cn

职位仓库高级版
图2。高级职位仓库访问

JobExplorer作业操作员讨论的接口 在接下来的章节中,将添加更多查询和控制元数据的功能。spring-doc.cadn.net.cn

查询仓库

在任何高级功能之前,最基本的需求是能够 查询仓库中的现有执行。该功能是 由JobExplorer接口:spring-doc.cadn.net.cn

public interface JobExplorer {

    List<JobInstance> getJobInstances(String jobName, int start, int count);

    JobExecution getJobExecution(Long executionId);

    StepExecution getStepExecution(Long jobExecutionId, Long stepExecutionId);

    JobInstance getJobInstance(Long instanceId);

    List<JobExecution> getJobExecutions(JobInstance jobInstance);

    Set<JobExecution> findRunningJobExecutions(String jobName);
}

从其方法签名可见,JobExplorer是 的只读版本 这JobRepository,并且,像JobRepository,可以通过使用 工厂豆。spring-doc.cadn.net.cn

以下示例展示了如何配置JobExplorer在爪哇语中:spring-doc.cadn.net.cn

Java 配置
...
// This would reside in your DefaultBatchConfiguration extension
@Bean
public JobExplorer jobExplorer() throws Exception {
	JobExplorerFactoryBean factoryBean = new JobExplorerFactoryBean();
	factoryBean.setDataSource(this.dataSource);
	return factoryBean.getObject();
}
...

以下示例展示了如何配置JobExplorer以XML形式表示:spring-doc.cadn.net.cn

XML 配置
<bean id="jobExplorer" class="org.spr...JobExplorerFactoryBean"
      p:dataSource-ref="dataSource" />

在本章早些时候,我们提到你可以修改表前缀 关于JobRepository以支持不同的版本或模式。因为 这JobExplorer同样适用于相同的表,同时还需要设置前缀的能力。spring-doc.cadn.net.cn

以下示例展示了如何为JobExplorer在爪哇语中:spring-doc.cadn.net.cn

Java 配置
...
// This would reside in your DefaultBatchConfiguration extension
@Bean
public JobExplorer jobExplorer() throws Exception {
	JobExplorerFactoryBean factoryBean = new JobExplorerFactoryBean();
	factoryBean.setDataSource(this.dataSource);
	factoryBean.setTablePrefix("SYSTEM.");
	return factoryBean.getObject();
}
...

以下示例展示了如何为JobExplorer以XML形式表示:spring-doc.cadn.net.cn

XML 配置
<bean id="jobExplorer" class="org.spr...JobExplorerFactoryBean"
		p:tablePrefix="SYSTEM."/>

职位注册

一个职位注册(及其父接口,JobLocator)并非强制,但可以 如果你想跟踪上下文中有哪些职位可用,这很有用。它也是 在应用环境中集中收集创建的作业非常有用 其他地方(例如在儿童语境中)。你也可以用自定义职位注册实现 作注册作业的名称和其他属性。 该框架仅提供一种实现,基于一个简单的 从作业名称映射到作业实例。spring-doc.cadn.net.cn

使用@EnableBatchProcessing一个职位注册为你提供。 以下示例展示了如何配置自己的职位注册:spring-doc.cadn.net.cn

...
// This is already provided via the @EnableBatchProcessing but can be customized via
// overriding the bean in the DefaultBatchConfiguration
@Override
@Bean
public JobRegistry jobRegistry() throws Exception {
	return new MapJobRegistry();
}
...

以下示例展示了如何包含职位注册对于用XML定义的作业:spring-doc.cadn.net.cn

<bean id="jobRegistry" class="org.springframework.batch.core.configuration.support.MapJobRegistry" />

你可以填充一个职位注册以下方式之一:通过使用 豆后处理器,或使用智能初始化单例,或使用 注册商生命周期组件。接下来的章节将介绍这些机制。spring-doc.cadn.net.cn

JobRegistryBeanPostProcessor

这是一种Beans后处理器,可以在所有作业创建时注册。spring-doc.cadn.net.cn

以下示例展示了如何包含JobRegistryBeanPostProcessor为了一份工作 在 Java 中定义:spring-doc.cadn.net.cn

Java 配置
@Bean
public JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor(JobRegistry jobRegistry) {
    JobRegistryBeanPostProcessor postProcessor = new JobRegistryBeanPostProcessor();
    postProcessor.setJobRegistry(jobRegistry);
    return postProcessor;
}

以下示例展示了如何包含JobRegistryBeanPostProcessor为了一份工作 以XML定义:spring-doc.cadn.net.cn

XML 配置
<bean id="jobRegistryBeanPostProcessor" class="org.spr...JobRegistryBeanPostProcessor">
    <property name="jobRegistry" ref="jobRegistry"/>
</bean>

虽然并非绝对必要,但后处理器在 示例如下身份证以便将其包含在子节点中 上下文(例如,作为父豆定义)和所有创造的作业 这些也将自动注册。spring-doc.cadn.net.cn

折旧

从5.2版本开始,JobRegistryBeanPostProcessor类被弃用,取而代之的是JobRegistrySmartInitializingSingleton,参见JobRegistrySmartInitializingSingletonspring-doc.cadn.net.cn

JobRegistrySmartInitializingSingleton

这是一艘SmartInitializingSingleton它会在作业注册表中登记所有单例任务。spring-doc.cadn.net.cn

以下示例展示了如何定义JobRegistrySmartInitializingSingleton在爪哇语中:spring-doc.cadn.net.cn

Java 配置
@Bean
public JobRegistrySmartInitializingSingleton jobRegistrySmartInitializingSingleton(JobRegistry jobRegistry) {
    return new JobRegistrySmartInitializingSingleton(jobRegistry);
}

以下示例展示了如何定义JobRegistrySmartInitializingSingleton以XML形式表示:spring-doc.cadn.net.cn

XML 配置
<bean class="org.springframework.batch.core.configuration.support.JobRegistrySmartInitializingSingleton">
    <property name="jobRegistry" ref="jobRegistry" />
</bean>

AutomaticJobRegistrar

这是一个生命周期组件,用于创建子上下文并从中注册作业 上下文的创建过程。这样做的一个好处是,虽然职位名称会被 子上下文在注册表中仍然必须是全球唯一的,它们的依赖关系 可以有“自然”的名字。例如,你可以创建一组XML配置文件 每个都只有一个工作,但都对物品阅读器其中 同一个豆子的名字,例如读者.如果所有这些文件都导入到同一个上下文中, 读者定义会相互冲突并覆盖,但自动 登记官,这种情况是避免的。这使得整合已贡献的岗位变得更容易 应用程序的独立模块。spring-doc.cadn.net.cn

以下示例展示了如何包含AutomaticJobRegistrar对于定义的作业 在爪哇语中:spring-doc.cadn.net.cn

Java 配置
@Bean
public AutomaticJobRegistrar registrar() {

    AutomaticJobRegistrar registrar = new AutomaticJobRegistrar();
    registrar.setJobLoader(jobLoader());
    registrar.setApplicationContextFactories(applicationContextFactories());
    registrar.afterPropertiesSet();
    return registrar;

}

以下示例展示了如何包含AutomaticJobRegistrar对于定义的作业 以XML形式表示:spring-doc.cadn.net.cn

XML 配置
<bean class="org.spr...AutomaticJobRegistrar">
   <property name="applicationContextFactories">
      <bean class="org.spr...ClasspathXmlApplicationContextsFactoryBean">
         <property name="resources" value="classpath*:/config/job*.xml" />
      </bean>
   </property>
   <property name="jobLoader">
      <bean class="org.spr...DefaultJobLoader">
         <property name="jobRegistry" ref="jobRegistry" />
      </bean>
   </property>
</bean>

注册商具有两个强制性质:数组应用上下文工厂(由 方便的工厂豆(如前述示例)以及JobLoader.这JobLoader负责管理子上下文的生命周期, 在职位注册.spring-doc.cadn.net.cn

应用上下文工厂是 负责创建子语境。最常见的用法 如前例所示,使用ClassPathXmlApplicationContextFactory.其中之一 该工厂的特点是默认复制部分 从父上下文向下映射到子上下文的配置。因此,对于 实例中,你无需重新定义PropertyPlaceholderConfigurer或AOP 在子节点中的配置,前提是配置应与 父母。spring-doc.cadn.net.cn

你可以使用AutomaticJobRegistrar在 与 a 的合取JobRegistryBeanPostProcessor(只要你也使用DefaultJobLoader). 例如,如果有工作机会,这可能是理想的 在主父上下文中定义,同时在子上下文中 地点。spring-doc.cadn.net.cn

作业操作员

如前所述,该JobRepository提供元数据的 CRUD作,以及JobExplorer提供对 元数据。然而,这些作结合使用时最为有用 执行常见的监控任务,如停止、重启,或 如批处理操作员通常所做的那样,对作业进行总结。春季批次 提供以下类型的作作业操作员接口:spring-doc.cadn.net.cn

public interface JobOperator {

    List<Long> getExecutions(long instanceId) throws NoSuchJobInstanceException;

    List<Long> getJobInstances(String jobName, int start, int count)
          throws NoSuchJobException;

    Set<Long> getRunningExecutions(String jobName) throws NoSuchJobException;

    String getParameters(long executionId) throws NoSuchJobExecutionException;

    Long start(String jobName, String parameters)
          throws NoSuchJobException, JobInstanceAlreadyExistsException;

    Long restart(long executionId)
          throws JobInstanceAlreadyCompleteException, NoSuchJobExecutionException,
                  NoSuchJobException, JobRestartException;

    Long startNextInstance(String jobName)
          throws NoSuchJobException, JobParametersNotFoundException, JobRestartException,
                 JobExecutionAlreadyRunningException, JobInstanceAlreadyCompleteException;

    boolean stop(long executionId)
          throws NoSuchJobExecutionException, JobExecutionNotRunningException;

    String getSummary(long executionId) throws NoSuchJobExecutionException;

    Map<Long, String> getStepExecutionSummaries(long executionId)
          throws NoSuchJobExecutionException;

    Set<String> getJobNames();

}

前面的作代表来自许多不同接口的方法,例如JobLauncher,JobRepository,JobExplorer职位注册.因此, 提供实现作业操作员 (SimpleJobOperator)存在许多依赖关系。spring-doc.cadn.net.cn

以下示例展示了Beans定义的典型SimpleJobOperator在爪哇语中:spring-doc.cadn.net.cn

 /**
  * All injected dependencies for this bean are provided by the @EnableBatchProcessing
  * infrastructure out of the box.
  */
 @Bean
 public SimpleJobOperator jobOperator(JobExplorer jobExplorer,
                                JobRepository jobRepository,
                                JobRegistry jobRegistry,
                                JobLauncher jobLauncher) {

	SimpleJobOperator jobOperator = new SimpleJobOperator();
	jobOperator.setJobExplorer(jobExplorer);
	jobOperator.setJobRepository(jobRepository);
	jobOperator.setJobRegistry(jobRegistry);
	jobOperator.setJobLauncher(jobLauncher);

	return jobOperator;
 }

以下示例展示了Beans定义的典型SimpleJobOperator以XML形式表示:spring-doc.cadn.net.cn

<bean id="jobOperator" class="org.spr...SimpleJobOperator">
    <property name="jobExplorer">
        <bean class="org.spr...JobExplorerFactoryBean">
            <property name="dataSource" ref="dataSource" />
        </bean>
    </property>
    <property name="jobRepository" ref="jobRepository" />
    <property name="jobRegistry" ref="jobRegistry" />
    <property name="jobLauncher" ref="jobLauncher" />
</bean>

从5.0版本开始,@EnableBatchProcessing注释会自动注册作业作子 BEAN 在应用的语境下。spring-doc.cadn.net.cn

如果你在作业仓库设置了表前缀,别忘了在作业资源管理器里也设置。

JobParametersIncrementer

大多数方法在作业操作员是 不言自明,你可以在Java文档中找到更详细的界面说明。然而,startNextInstance方法值得注意。这 方法总是从一个新的实例开始工作. 如果出现严重问题,这会非常有用作业执行以及工作需要从头重新开始。与JobLauncher(这需要新的作业参数触发新对象JobInstance),如果参数不同于 任意之前的参数集合,即startNextInstance方法JobParametersIncrementer工作强制工作转给 新实例:spring-doc.cadn.net.cn

public interface JobParametersIncrementer {

    JobParameters getNext(JobParameters parameters);

}

合同JobParametersIncrementer是 给定一个 JobParameters 对象,它返回了“next”作业参数通过递增其可能包含的任何必要的值来实现对象。这 策略之所以有用,是因为框架无法知道具体情况 对作业参数让它成为“下一个” 实例。例如,如果 中唯一的值作业参数是日期,下一个实例 应该被创造出来,这个价值应该增加一天还是一天 比如工作是每周的,比如说是每周的?任何情况都可以如此 帮助识别工作, 如下示例所示:spring-doc.cadn.net.cn

public class SampleIncrementer implements JobParametersIncrementer {

    public JobParameters getNext(JobParameters parameters) {
        if (parameters==null || parameters.isEmpty()) {
            return new JobParametersBuilder().addLong("run.id", 1L).toJobParameters();
        }
        long id = parameters.getLong("run.id",1L) + 1;
        return new JobParametersBuilder().addLong("run.id", id).toJobParameters();
    }
}

在这个例子中,键为run.id习惯于 区分JobInstances.如果作业参数传递 为空,它可以是 假设工作此前从未举办过 因此,其初始状态可以被返回。不过,如果没有,老的 获得值,递增一后返回。spring-doc.cadn.net.cn

对于用 Java 定义的作业,你可以将递增符与工作通过增量器架构商提供了方法如下:spring-doc.cadn.net.cn

@Bean
public Job footballJob(JobRepository jobRepository) {
    return new JobBuilder("footballJob", jobRepository)
    				 .incrementer(sampleIncrementer())
    				 ...
                     .build();
}

对于用XML定义的作业,你可以将增量符与工作通过增量器属性在命名空间中,具体如下:spring-doc.cadn.net.cn

<job id="footballJob" incrementer="sampleIncrementer">
    ...
</job>

停止工作

最常见的用例之一是作业操作员优雅地停止了 工作:spring-doc.cadn.net.cn

Set<Long> executions = jobOperator.getRunningExecutions("sampleJob");
jobOperator.stop(executions.iterator().next());

关闭不会立即发生,因为没有强制执行的办法 立即关闭,尤其是当执行正在进行时 框架无法控制的开发代码,例如 商务服务。然而,一旦控制权恢复到...... 框架,它设定了当前的状态步执行批次状态。停止保存它,并做同样的事 对于作业执行然后结束。spring-doc.cadn.net.cn

终止工作

一个作业执行失败可以是 重启(如果工作可重启)。一个状态为被遗弃的框架无法重启。 这被遗弃的状态也用于STEP中 执行时,在重启作业执行中标记为可跳过。如果 作业正在运行,遇到一个已被标记的步骤被遗弃的在之前失败的作业执行中, 进入下一步(根据作业流定义 以及步骤执行退出状态)。spring-doc.cadn.net.cn

如果进程死了 (击杀 -9或服务器 失败),当然,工作不是运行,而是JobRepository具有 没人告诉过,流程死了没人告诉我。你 必须手动告诉它你知道执行失败了 或者应视为已终止(将其状态更改为失败被遗弃的).这是 这是一个商业决策,而没有自动化的方法。更改 地位失败只有在可重启且你确定重启数据有效的情况下。spring-doc.cadn.net.cn