Appearance
运行 Spring Batch 作业
本教程详细讲解 Spring Batch 作业的两种运行方式:命令行启动和 Web 容器启动。通过实际代码示例和最佳实践,帮助初学者掌握作业运行机制。
一、核心运行组件
最小启动要求
运行批处理作业需要两个核心组件:
Job
- 定义批处理逻辑JobLauncher
- 作业启动器
两者可部署在同一上下文或不同上下文中。
NOTE
部署模式差异
- 命令行启动:每个作业在新 JVM 中运行,拥有独立的
JobLauncher
- Web 容器启动:多个请求共享异步配置的
JobLauncher
二、命令行运行作业
企业级调度系统通常通过命令行触发作业,因其直接与操作系统进程交互。
1. CommandLineJobRunner
Spring Batch 提供的命令行入口类,主要功能:
必需参数:
参数 | 说明 |
---|---|
jobPath | 包含完整作业配置的 XML/Kotlin 文件路径 |
jobName | 要运行的作业名称 |
参数格式示例:
bash
java CommandLineJobRunner io.spring.EndOfDayJobConfig endOfDay \
schedule.date=2023-12-01,java.time.LocalDate,true \
vendor.id=456,java.lang.Long,false
参数标识说明
后缀 true/false
声明参数是否为标识参数:
schedule.date=...,true
→ 作业标识参数vendor.id=...,false
→ 普通参数
Kotlin 作业配置示例:
kotlin
@Configuration
@EnableBatchProcessing
class EndOfDayJobConfig {
@Bean
fun endOfDayJob(jobRepository: JobRepository): Job {
return JobBuilder("endOfDay", jobRepository)
.start(step1())
.build()
}
@Bean
fun step1(jobRepository: JobRepository,
transactionManager: PlatformTransactionManager) =
StepBuilder("step1", jobRepository)
.tasklet({ _, _ -> null }, transactionManager)
.build()
}
2. 退出码处理
调度系统通过退出码判断作业执行结果:
kotlin
// 自定义退出码映射器
class CustomExitMapper : ExitCodeMapper {
override fun intValue(exitCode: String): Int {
return when(exitCode) {
"COMPLETED" -> 0
"FAILED" -> 1
"RESTART" -> 10 // 特殊代码需调度器支持
else -> 2
}
}
}
注意事项
- 默认映射规则:
0
= 成功1
= 通用错误2
= 作业启动错误
- 声明自定义映射器需注册为根级 Bean
三、Web 容器运行作业
适用于报表生成、即席作业等需要 HTTP 触发的场景,需异步启动避免阻塞请求。
异步启动流程:
Kotlin 控制器实现:
kotlin
@Controller
class JobLauncherController(
@Autowired private val jobLauncher: JobLauncher,
@Autowired private val endOfDayJob: Job
) {
@GetMapping("/runJob")
fun launchJob(): ResponseEntity<String> {
val future = CompletableFuture.runAsync {
jobLauncher.run(endOfDayJob, JobParameters())
}
return ResponseEntity.accepted().body("作业已启动")
}
}
kotlin
// 会阻塞HTTP线程
jobLauncher.run(job, JobParameters())
kotlin
// 使用TaskExecutor实现非阻塞
@Bean
fun asyncJobLauncher(jobRepository: JobRepository): JobLauncher {
return TaskExecutorJobLauncher().apply {
setJobRepository(jobRepository)
setTaskExecutor(SimpleAsyncTaskExecutor())
}
}
四、关键配置说明
最佳实践
- Web 容器配置
kotlin
@Configuration
class BatchConfig {
@Bean
fun jobLauncher(jobRepository: JobRepository) =
TaskExecutorJobLauncher().apply {
setJobRepository(jobRepository)
setTaskExecutor(ThreadPoolTaskExecutor().apply {
corePoolSize = 5
maxPoolSize = 10
})
}
}
- 作业参数安全注入
kotlin
@Bean
fun jobParamValidator() = JobParametersValidator { parameters ->
if(!parameters.containsKey("run.date")) {
throw JobParametersInvalidException("缺少run.date参数")
}
}
CAUTION
安全警告
开放 HTTP 作业触发端点时:
- 添加身份验证
@PreAuthorize("hasRole('ADMIN')")
- 验证参数合法性防止恶意注入
- 限制并发启动次数
五、总结对比
启动方式 | 适用场景 | 优势 | 注意事项 |
---|---|---|---|
命令行启动 | 定时任务/调度系统 | 资源隔离,稳定性高 | 需处理退出码映射 |
Web 容器异步启动 | 用户触发/即席作业 | 集成便捷,响应快速 | 需防止资源耗尽 |
扩展知识
✅ 作业监听器:实现 JobExecutionListener
记录执行日志
✅ 参数增量器:使用 JobParametersIncrementer
自动生成运行ID
✅ 元数据管理:通过 JobExplorer
查询历史执行记录
通过本教程,您已掌握 Spring Batch 作业的核心启动机制,可根据实际需求选择最适合的运行方式。