运行 Job

启动批处理作业至少需要两件事:要启动的作业和 .两者都可以包含在同一个 context 或不同的上下文。例如,如果您从 命令行中,将为每个 .因此,每个 Job 有自己的 .但是,如果 您可以从 范围内的 Web 容器中运行,通常有一个(为异步作业配置 launching),多个请求调用以启动其作业。JobJobLauncherJobJobLauncherHttpRequestJobLauncherspring-doc.cn

从命令行运行 Job

如果要从企业运行作业 scheduler 中,命令行是主界面。这是因为 大多数调度程序(Quartz 除外,除非使用 )直接与 os 一起工作 进程,主要由 shell 脚本启动。有很多方法 启动除 shell 脚本之外的 Java 进程,例如 Perl、Ruby 或 甚至构建工具,例如 Ant 或 Maven。但是,因为大多数人 熟悉 shell 脚本,本示例重点介绍它们。NativeJobspring-doc.cn

The CommandLineJobRunner

因为启动作业的脚本必须启动 Java Virtual Machine 中,需要有一个类,其中包含一个 作为主要入口点。Spring Batch 提供了一个实现 ,用于此目的:。注意 这只是引导应用程序的一种方式。有 启动 Java 进程的方法有很多种,这个类绝不应该是 被视为确定的。执行四项任务:mainCommandLineJobRunnerCommandLineJobRunnerspring-doc.cn

所有这些任务都只需传入参数即可完成。 下表描述了所需的参数:spring-doc.cn

表 1.CommandLineJobRunner 参数

jobPathspring-doc.cn

XML 文件的位置,用于 创建一个 .此文件 应包含运行完整 .ApplicationContextJobspring-doc.cn

jobNamespring-doc.cn

要运行的作业的名称。spring-doc.cn

必须传入这些参数,路径在前,名称在后。所有参数 在这些被认为是作业参数后,它们被转换为对象, ,并且必须采用 .JobParametersname=valuespring-doc.cn

以下示例显示了作为作业参数传递给 Java 中定义的作业的日期:spring-doc.cn

<bash$ java CommandLineJobRunner io.spring.EndOfDayJobConfiguration endOfDay schedule.date=2007-05-05,java.time.LocalDate

以下示例显示了作为作业参数传递给 XML 中定义的作业的日期:spring-doc.cn

<bash$ java CommandLineJobRunner endOfDayJob.xml endOfDay schedule.date=2007-05-05,java.time.LocalDate

默认情况下,它使用隐式转换 用于标识作业参数的键/值对。但是,您可以显式指定 哪些作业参数正在标识,哪些不是,分别通过给它们加上 或 后缀。CommandLineJobRunnerDefaultJobParametersConvertertruefalsespring-doc.cn

在以下示例中, is 是一个标识作业参数,while is not:schedule.datevendor.idspring-doc.cn

<bash$ java CommandLineJobRunner endOfDayJob.xml endOfDay \
                                 schedule.date=2007-05-05,java.time.LocalDate,true \
                                 vendor.id=123,java.lang.Long,false
<bash$ java CommandLineJobRunner io.spring.EndOfDayJobConfiguration endOfDay \
                                 schedule.date=2007-05-05,java.time.LocalDate,true \
                                 vendor.id=123,java.lang.Long,false

您可以通过使用自定义 .JobParametersConverterspring-doc.cn

在大多数情况下,您需要使用 manifest 在 jar 中声明您的类。然而 为简单起见,该类被直接使用。此示例使用 Batch 的域语言中的示例。第一个 argument 是 ,这是完全限定的类名 添加到包含 Job 的配置类中。第二个参数 , 表示 作业名称。最后一个参数 , 被转换 转换为类型为 .mainEndOfDayio.spring.EndOfDayJobConfigurationendOfDayschedule.date=2007-05-05,java.time.LocalDateJobParameterjava.time.LocalDatespring-doc.cn

以下示例显示了 在 Java 中的配置示例:endOfDayspring-doc.cn

@Configuration
@EnableBatchProcessing
public class EndOfDayJobConfiguration {

    @Bean
    public Job endOfDay(JobRepository jobRepository, Step step1) {
        return new JobBuilder("endOfDay", jobRepository)
    				.start(step1)
    				.build();
    }

    @Bean
    public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
        return new StepBuilder("step1", jobRepository)
    				.tasklet((contribution, chunkContext) -> null, transactionManager)
    				.build();
    }
}

在大多数情况下,您需要使用 manifest 在 jar 中声明您的类。然而 为简单起见,该类被直接使用。此示例使用 Batch 的域语言中的示例。第一个 参数是 ,它是包含 .第二个参数表示作业名称。最后一个参数 , 将转换为 类型为 的对象。mainEndOfDayendOfDayJob.xmlJobendOfDay,schedule.date=2007-05-05,java.time.LocalDateJobParameterjava.time.LocalDatespring-doc.cn

以下示例显示了 in XML 的示例配置:endOfDayspring-doc.cn

<job id="endOfDay">
    <step id="step1" parent="simpleStep" />
</job>

<!-- Launcher details removed for clarity -->
<beans:bean id="jobLauncher"
         class="org.springframework.batch.core.launch.support.TaskExecutorJobLauncher" />

前面的示例过于简单,因为 通常在 Spring Batch 中运行批处理作业,但它用于显示两个主要的 的要求 : 和 .CommandLineJobRunnerJobJobLauncherspring-doc.cn

退出代码

从命令行启动批处理作业时,企业 经常使用 scheduler。大多数调度程序都相当愚蠢,只能工作 在流程级别。这意味着他们只知道一些 操作系统进程(例如它们调用的 shell 脚本)。 在这种情况下,与调度程序通信的唯一方法 关于作业的成功或失败是通过返回代码。一个 return code 是进程返回给调度程序的数字 以指示运行结果。在最简单的情况下,0 是 成功,1 是失败。但是,可能还有更复杂的 场景,例如“如果作业 A 返回 4,则启动作业 B,如果作业返回 5,则启动作业 B 下班 C。这种类型的行为在调度程序级别配置, 但重要的是,像 Spring Batch 这样的处理框架 提供一种方法来返回退出代码的数字表示形式 对于特定的批处理作业。在 Spring Batch 中,这是封装的 在 中,在 more 详情见第 5 章。为了讨论退出代码, 唯一需要知道的是,an 有一个 exit code 属性,该属性是 设置,并作为从 .将转换此字符串值 使用界面更改为数字:ExitStatusExitStatusJobExecutionJobLauncherCommandLineJobRunnerExitCodeMapperspring-doc.cn

public interface ExitCodeMapper {

    public int intValue(String exitCode);

}

an 的基本协定是,给定一个字符串 exit code 时,将返回一个数字表示形式。默认的 Job Runner 使用的实现是返回 0 表示完成、1 表示一般错误和 2 表示任何作业的实现 运行器错误,例如无法在提供的上下文中找到 A。如果有更多 complex 的 3 个值,则自定义 接口的实现 必须提供。因为 是创建 因此,AN AND 不能是 'wired together' 时,任何需要覆盖的值都必须是 自动装配。这意味着,如果在 、 在创建上下文后,它会注入到 Runner 中。都 需要做的是提供你自己的 作为根级 Bean 进行加载,并确保它是 跑步者。ExitCodeMapperSimpleJvmExitCodeMapperJobExitCodeMapperCommandLineJobRunnerApplicationContextExitCodeMapperBeanFactoryExitCodeMapperApplicationContextspring-doc.cn

从 Web 容器中运行作业

从历史上看,离线处理(例如批处理作业)一直是 从命令行启动,如前所述。但是,有 在许多情况下,从 启动 一个更好的选择。许多此类用例包括报告、临时作业 running 和 Web 应用程序支持。因为批处理作业(根据定义) 运行时间长,最关心的是启动 job 异步:HttpRequestspring-doc.cn

来自 Web 容器的异步作业Starters序列
图 1.来自 Web 容器的异步作业Starters序列

在这种情况下,控制器是 Spring MVC 控制器。请参阅 Spring Framework 参考指南,了解有关 Spring MVC 的更多信息。 控制器使用已配置为异步启动的 来启动 一个,该 立即返回一个 .它可能仍在运行。但是,此 非阻塞行为允许控制器立即返回,这 在处理 .以下清单 显示了一个例子:JobJobLauncherJobExecutionJobHttpRequestspring-doc.cn

@Controller
public class JobLauncherController {

    @Autowired
    JobLauncher jobLauncher;

    @Autowired
    Job job;

    @RequestMapping("/jobLauncher.html")
    public void handle() throws Exception{
        jobLauncher.run(job, new JobParameters());
    }
}