运行任务
至少,启动一个批处理作业需要两件事:要启动的Job和一个JobOperator。两者可以包含在同一个上下文中,也可以包含在不同的上下文中。例如,如果您从命令行启动作业,则每个Job都会实例化一个新的 JVM。因此,每个作业都有自己独立的JobOperator。然而,如果您在位于HttpRequest作用域内的 Web 容器中运行,则通常只有一个JobOperator(配置用于异步启动作业),多个请求会调用它来启动各自的作业。
从命令行运行作业
如果您想从企业级调度器运行作业,命令行是主要接口。这是因为大多数调度器(除了 Quartz,除非使用 NativeJob)直接操作系统进程,通常通过 shell 脚本启动。除了 shell 脚本外,还有许多方式可以启动 Java 进程,例如使用 Perl、Ruby,甚至构建工具如 Ant 或 Maven。然而,由于大多数人熟悉 shell 脚本,本示例将重点介绍它们。
CommandLineJobOperator
由于启动作业的脚本必须启动一个 Java 虚拟机,因此需要一个包含 main 方法的类作为主要入口点。Spring Batch 提供了一个实现来满足此目的:CommandLineJobOperator。请注意,这只是引导应用程序的一种方式。启动 Java 进程的方法有很多,绝不应将此类视为唯一标准。CommandLineJobOperator 执行以下四项任务:
-
加载适当的
ApplicationContext。 -
将命令行参数解析为
JobParameters。 -
根据参数定位合适的工作。
-
使用应用上下文中提供的
JobOperator来启动作业。
所有这些任务仅通过传入的参数即可完成。 下表描述了所需的参数:
|
用于创建 |
|
要在作业上执行的操作名称。可以是 [ |
|
根据操作的不同,这可以是要启动的作业名称,或者是要停止、重启、放弃或恢复的作业的执行 ID。 |
启动作业时,这些之后的所有参数都被视为作业参数,会被转换为一个 JobParameters 对象,
并且必须符合 name=value,type,identifying 格式。在停止、重启、放弃或恢复作业的情况下,第 4 个参数应为 jobExecutionId,
其余所有参数将被忽略。
以下示例展示了将日期作为作业参数传递给在 Java 中定义的作业:
<bash$ java CommandLineJobOperator io.spring.EndOfDayJobConfiguration start endOfDay schedule.date=2007-05-05,java.time.LocalDate
默认情况下,CommandLineJobOperator 使用 DefaultJobParametersConverter 隐式地将键/值对转换为标识性作业参数。但是,您可以通过分别后缀 true 或 false 来显式指定哪些作业参数是标识性的,哪些不是。
在以下示例中,schedule.date 是一个标识性作业参数,而 vendor.id 不是:
<bash$ java CommandLineJobOperator io.spring.EndOfDayJobConfiguration start endOfDay \
schedule.date=2007-05-05,java.time.LocalDate,true \
vendor.id=123,java.lang.Long,false
您可以通过在 CommandLineJobOperator 上设置自定义的 JobParametersConverter 来覆盖此行为。
退出代码
从命令行启动批处理作业时,通常会使用企业级调度器。大多数调度器相当笨拙,仅在进程级别工作。这意味着它们只知道某些操作系统进程(例如它们调用的 shell 脚本)。在此场景中,向调度器传达作业成功或失败的唯一方式是通过返回码。A
返回码是一个由进程返回给调度器的数字,
用于指示运行结果。在最简单的情况下,0 表示成功,1 表示失败。然而,可能存在更复杂的场景,例如“如果作业 A 返回 4,则启动作业 B;如果返回 5,则启动作业 C。” 此类行为是在调度器级别配置的,
但重要的是,像 Spring Batch 这样的处理框架需要提供一种方式,
以返回特定批处理作业的退出码的数值表示。在 Spring Batch 中,这被封装在一个ExitStatus中,第 5 章将对此进行更详细的介绍。就讨论退出码而言,唯一需要知道的重要事项是,ExitStatus 拥有一个由框架(或开发人员)设置的退出码属性,并作为从 JobOperator 返回的 JobExecution 的一部分被返回。CommandLineJobOperator 使用 ExitCodeMapper 接口将此字符串值转换为数字:
public interface ExitCodeMapper {
int intValue(String exitCode);
}
ExitCodeMapper 的基本约定是:给定一个字符串形式的退出代码,将返回一个数字表示。作业运行器使用的默认实现是 SimpleJvmExitCodeMapper,它在任务完成时返回 0,在发生通用错误时返回 1,在出现任何作业运行器错误(例如在提供的上下文中找不到 Job)时返回 2。如果需要比上述三个值更复杂的逻辑,则必须通过将其设置在 CommandLineJobOperator 上来提供 ExitCodeMapper 接口的自定义实现。
在 Web 容器内运行作业
历史上,离线处理(例如批处理作业)如前所述是从命令行启动的。然而,在许多情况下,从 HttpRequest 启动是更好的选择。许多此类用例包括报表生成、临时作业运行以及 Web 应用程序支持。由于批处理作业(根据其定义)运行时间较长,因此最重要的关注点是异步启动该作业:
此情况下的控制器是一个 Spring MVC 控制器。有关 Spring MVC 的更多信息,请参阅 Spring Framework 参考指南。
该控制器通过使用已配置为 异步 启动的 JobOperator 来启动一个 Job,它会立即返回一个 JobExecution。Job 可能仍在运行。然而,这种非阻塞行为允许控制器立即返回,这在处理 HttpRequest 时是必需的。以下列表展示了一个示例:
@Controller
public class JobOperatorController {
@Autowired
JobOperator jobOperator;
@Autowired
Job job;
@RequestMapping("/jobOperator.html")
public void handle() throws Exception{
jobOperator.start(job, new JobParameters());
}
}