此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Batch 文档 5.1.2spring-doc.cn

此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Batch 文档 5.1.2spring-doc.cn

到目前为止,和 接口都是 讨论。它们共同代表了 Job 和 Basic 的简单启动 批处理域对象的 CRUD 操作:JobLauncherJobRepositoryspring-doc.cn

作业存储库
图 1.作业存储库

A 使用 创建新对象并运行它们。 和实现 以后对基本更新使用相同的 在 . 基本操作足以满足简单的场景。但是,在大批量 具有数百个批处理作业和复杂调度的环境 要求,则需要对元数据进行更高级的访问:JobLauncherJobRepositoryJobExecutionJobStepJobRepositoryJobspring-doc.cn

作业存储库高级
图 2.高级作业存储库访问

和 接口,这些接口将进行讨论 在接下来的部分中,添加用于查询和控制元数据的其他功能。JobExplorerJobOperatorspring-doc.cn

查询存储库

在任何高级功能之前,最基本的需求是能够 查询存储库中的现有执行。此功能是 由 interface 提供:JobExplorerspring-doc.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);
}

从其方法签名中可以明显看出,是 的 ,并且与 一样,它可以通过使用 工厂 Bean 的 Bean 中。JobExplorerJobRepositoryJobRepositoryspring-doc.cn

以下示例演示如何在 Java 中配置 a:JobExplorerspring-doc.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();
}
...

以下示例显示了如何在 XML 中配置 a:JobExplorerspring-doc.cn

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

在本章的前面部分,我们注意到您可以修改表前缀 的允许不同的版本或架构。因为 对于相同的表,它还需要能够设置前缀。JobRepositoryJobExplorerspring-doc.cn

以下示例显示了如何在 Java 中为 a 设置表前缀:JobExplorerspring-doc.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();
}
...

以下示例演示如何在 XML 中设置 a 的表前缀:JobExplorerspring-doc.cn

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

JobRegistry (作业注册表)

A(及其父接口 )不是必需的,但可以是 如果要跟踪上下文中可用的作业,则很有用。它也是 在创建作业时,用于在应用程序上下文中集中收集作业 其他位置(例如,在子上下文中)。您还可以使用自定义实施 操作已注册作业的名称和其他属性。 框架只提供了一个实现,它基于一个简单的 从 Job Name 映射到 Job Instance。JobRegistryJobLocatorJobRegistryspring-doc.cn

使用 时,将为您提供 a。 以下示例显示如何配置您自己的 :@EnableBatchProcessingJobRegistryJobRegistryspring-doc.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();
}
...

以下示例显示了如何包含 for a for a job defined in XML:JobRegistryspring-doc.cn

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

您可以通过以下方式之一填充 a:通过使用 bean 后处理器,或者通过使用智能初始化单例或使用 注册商生命周期组件。接下来的各节将介绍这些机制。JobRegistryspring-doc.cn

JobRegistryBeanPostProcessor

这是一个 bean 后处理器,可以在创建所有作业时注册它们。spring-doc.cn

以下示例显示了如何为 job 添加 在 Java 中定义:JobRegistryBeanPostProcessorspring-doc.cn

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

以下示例显示了如何为 job 添加 在 XML 中定义:JobRegistryBeanPostProcessorspring-doc.cn

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

尽管并非绝对必要,但 example 已被赋予一个,以便它可以包含在 Child 中 contexts(例如,作为父 Bean 定义)并导致创建所有作业 那里也会自动注册。idspring-doc.cn

折旧

从版本 5.2 开始,该类已被弃用,取而代之的是 ,请参阅 JobRegistrySmartInitializingSingletonJobRegistryBeanPostProcessorJobRegistrySmartInitializingSingletonspring-doc.cn

JobRegistrySmartInitializingSingleton

这是一个在 job 注册表中注册所有 singleton job 的 a。SmartInitializingSingletonspring-doc.cn

以下示例演示如何在 Java 中定义 a:JobRegistrySmartInitializingSingletonspring-doc.cn

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

下面的示例演示如何在 XML 中定义 a:JobRegistrySmartInitializingSingletonspring-doc.cn

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

自动作业注册器

这是一个生命周期组件,用于创建子上下文并从中注册作业 上下文。这样做的一个好处是,虽然 子上下文在 Registry 中仍然必须是全局唯一的,它们的依赖项 可以有 “natural” 名称。因此,例如,您可以创建一组 XML 配置文件 每个 Job 只有一个 Job ,但 an 的定义不同,其中 相同的 Bean 名称,例如 .如果所有这些文件都导入到同一上下文中,则 Reader 定义会相互冲突并覆盖,但是,使用 Automatic registrar 的 intent 和未加密的 intent 的 x这使得集成 应用程序的单独模块。ItemReaderreaderspring-doc.cn

以下示例显示了如何包含定义的 for a job defined 在 Java 中:AutomaticJobRegistrarspring-doc.cn

Java 配置
@Bean
public AutomaticJobRegistrar registrar() {

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

}

以下示例显示了如何包含定义的 for a job defined 在 XML 中:AutomaticJobRegistrarspring-doc.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>

registrar 有两个必需属性:一个数组(从 方便的工厂 Bean)和 .负责管理子上下文的生命周期,并且 在 中注册作业。ApplicationContextFactoryJobLoaderJobLoaderJobRegistryspring-doc.cn

的 负责创建子上下文。最常见的用法 是(如前面的示例所示)来使用 .其中之一 这个工厂的特点是,默认情况下,它会复制一些 configuration down 从 parent context 到 child。因此,对于 实例,则无需重新定义 or AOP 配置,前提是它应与 父母。ApplicationContextFactoryClassPathXmlApplicationContextFactoryPropertyPlaceholderConfigurerspring-doc.cn

您可以在 与 a 结合使用(只要您也使用 )。 例如,如果有工作,这可能是可取的 在主父上下文和子上下文中定义 地点。AutomaticJobRegistrarJobRegistryBeanPostProcessorDefaultJobLoaderspring-doc.cn

折旧

从版本 5.2 开始,该类已被弃用,取而代之的是 ,请参阅 JobRegistrySmartInitializingSingletonJobRegistryBeanPostProcessorJobRegistrySmartInitializingSingletonspring-doc.cn

JobOperator (作业操作员)

如前所述,它提供对元数据的 CRUD 操作,并且 提供对 元数据。但是,这些操作在一起使用时最有用 执行常见监控任务,例如停止、重新启动或 总结 Job,这通常是由 Batch Operator 完成的。Spring Batch 在界面中提供了以下类型的操作:JobRepositoryJobExplorerJobOperatorspring-doc.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();

}

上述操作表示来自许多不同接口的方法,例如 、 、 和 。因此, 提供的 () 实现具有许多依赖项。JobLauncherJobRepositoryJobExplorerJobRegistryJobOperatorSimpleJobOperatorspring-doc.cn

以下示例显示了 Java 中的典型 bean 定义:SimpleJobOperatorspring-doc.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;
 }

以下示例显示了 XML 中的典型 bean 定义:SimpleJobOperatorspring-doc.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 开始,注解会自动注册一个作业操作员 Bean 在应用程序上下文中。@EnableBatchProcessingspring-doc.cn

如果您在作业存储库上设置了表前缀,请不要忘记在作业资源管理器中也设置它。
如果您在作业存储库上设置了表前缀,请不要忘记在作业资源管理器中也设置它。

JobParametersIncrementer (作业参数增量器)

上的大多数方法都是 一目了然,您可以在界面的 Javadoc 中找到更详细的解释。但是,该方法值得注意。这 方法始终启动 . 如果 a 中存在严重问题并且需要从头开始,这将非常有用。与(需要一个触发 new 的新对象)不同,如果参数与 任何前面的参数集,该方法都使用 Tied to 来强制 to a 新建实例:JobOperatorstartNextInstanceJobJobExecutionJobJobLauncherJobParametersJobInstancestartNextInstanceJobParametersIncrementerJobJobspring-doc.cn

public interface JobParametersIncrementer {

    JobParameters getNext(JobParameters parameters);

}

的合约是 给定一个 JobParameters 对象,它通过增加它可能包含的任何必要值来返回 “next” 对象。这 策略很有用,因为框架无法知道 将其设为“下一个”的更改 实例。例如,如果 中的唯一值是 date 和 next 实例 应该创建,该值应增加 1 天或 1 周(例如,如果工作是每周)?任何 有助于识别 、 的数值 如下例所示:JobParametersIncrementerJobParametersJobParametersJobParametersJobspring-doc.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();
    }
}

在此示例中,键为 区分。如果传入的值为 null,则可以为 假设 以前从未运行 因此,可以返回其初始状态。但是,如果不是,则旧的 value 被获取,递增 1 并返回。run.idJobInstancesJobParametersJobspring-doc.cn

对于在 Java 中定义的作业,您可以通过构建器中提供的方法将 incrementer 与 关联,如下所示:Jobincrementerspring-doc.cn

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

对于在 XML 中定义的作业,您可以通过命名空间中的属性将 incrementer 与 a 关联,如下所示:Jobincrementerspring-doc.cn

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

停止作业

最常见的用例之一是正常停止 工作:JobOperatorspring-doc.cn

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

关闭不是立即的,因为没有办法强制 立即关闭,尤其是在执行当前处于 开发人员代码,例如 商业服务。但是,一旦控制权返回到 框架中,它将当前状态设置为 ,保存它,并执行相同的操作 对于整理前。StepExecutionBatchStatus.STOPPEDJobExecutionspring-doc.cn

中止作业

任务执行可以是 restarted (如果 是可重启的)。状态为 的任务执行 Framework 无法重新启动。 状态也用于步骤 executions 在重新启动的任务执行中将其标记为可跳过。如果 作业正在运行,并遇到在上一个失败的作业执行中标记的步骤,则 继续执行下一步(由 Job Flow 定义确定 和步骤执行退出状态)。FAILEDJobABANDONEDABANDONEDABANDONEDspring-doc.cn

如果进程已终止( 或服务器 failure),该作业当然不会运行,但 无法知道,因为在过程结束之前没有人告诉它。你 必须手动告诉它您知道执行失败 或应被视为已中止(将其状态更改为 或 )。这是 一个商业决策,没有办法自动化它。更改 status 设置为仅当它是可重启的并且您知道重启数据有效时。kill -9JobRepositoryFAILEDABANDONEDFAILEDspring-doc.cn