在 Spring Batch 中,嵌套 Job(Nested Job) 是指将一个或多个独立的 Job 作为另一个父 Job 的步骤(Step)来执行的架构模式。核心是通过 JobStep 组件实现 Job 的层级调用,形成父子执行关系。如下图:

上图执行流程如下:父 Job 按顺序执行 Steps(常规 Step → JobStep → 常规 Step),如果遇到 JobStep 时,触发子 Job 的完整执行周期(包括其所有 Steps,即子Job1、子Job2)。注意:子 Job 执行状态(成功/失败)决定父 Job 后续流程。
在 Spring Batch 中,JobStepBuilder 是一个关键的构建器类,用于创建一种特殊的步骤(Step)—— 作业步骤(JobStep)。作业步骤允许在一个作业中嵌套执行另一个独立的作业,从而实现复杂的批处理编排。
JobStepBuilder 是 StepBuilder 的扩展,专门用于构建作业步骤。其核心方法包括:
job(Job job):指定要嵌套执行的作业。
launcher(JobLauncher jobLauncher):指定作业启动器(可选,默认使用父作业的启动器)。
parametersExtractor(JobParametersExtractor extractor):从父作业传递参数到子作业。
on(String exitStatus):定义子作业执行后的路由规则(类似普通步骤)。
当前示例将展示“作业嵌套(Job Nesting)”的基本用法,创建一个 parentJob,该 Job 下面有两个子 Job(childJob1 和 childJob2),如下图:

要实现该示例,具体步骤如下:
(1)修改 application.properties 配置,添加如下内容:
spring.batch.job.names=parentJob
上述配置通过 spring.batch.job.names 指定了应用启动时自动执行的 Job 名称。当您设置这个属性时,应用会在启动后立即运行名为 parentJob 的批处理作业。
(2)创建 BatchConfig 配置类,代码如下:
package com.hxstrive.spring_batch.jobNestedDemo.config;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.builder.JobStepBuilder;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
/**
* Spring Batch 配置类
* @author hxstrive.com
*/
@Configuration
public class BatchConfig {
// 用于创建和配置 Job 对象的工厂类
@Autowired
private JobBuilderFactory jobBuilderFactory;
// 用于创建和配置 Step 对象的工厂类
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired
private JobLauncher launcher;
// 创建 Step 对象
@Bean
public Step jobNestedDemoStep1() {
return stepBuilderFactory.get("jobNestedDemoStep1").tasklet(new Tasklet() {
@Override
public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
System.out.println(Thread.currentThread().getName() + " jobNestedDemoStep1");
return RepeatStatus.FINISHED; // 返回 FINISHED 表明任务执行结束
}
}).build();
}
@Bean
public Step jobNestedDemoStep2() {
return stepBuilderFactory.get("jobNestedDemoStep2").tasklet(new Tasklet() {
@Override
public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
System.out.println(Thread.currentThread().getName() + " jobNestedDemoStep2");
return RepeatStatus.FINISHED; // 返回 FINISHED 表明任务执行结束
}
}).build();
}
@Bean
public Step jobNestedDemoStep3() {
return stepBuilderFactory.get("jobNestedDemoStep3").tasklet(new Tasklet() {
@Override
public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
System.out.println(Thread.currentThread().getName() + " jobNestedDemoStep3");
return RepeatStatus.FINISHED; // 返回 FINISHED 表明任务执行结束
}
}).build();
}
// 创建 Job 对象
// Job 类型的 Step,特殊的 Step
@Bean
public Job jobNestedDemoJob1() {
return jobBuilderFactory.get("jobNestedDemoJob1")
.start(jobNestedDemoStep1())
.next(jobNestedDemoStep2())
.build();
}
@Bean
public Job jobNestedDemoJob2() {
return jobBuilderFactory.get("jobNestedDemoJob2")
.start(jobNestedDemoStep3())
.build();
}
// 创建子JOB对象,通过 JobStepBuilder 将子作业转换为父作业中的一个步骤
@Bean
public Step childJob1(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new JobStepBuilder(new StepBuilder("childJob1"))
.job(jobNestedDemoJob1()) // 指定要嵌套的子作业
.launcher(launcher) // 指定作业启动器
.repository(jobRepository) // 指定作业仓库
.transactionManager(transactionManager) // 指定事务管理器
.build();
}
@Bean
public Step childJob2(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new JobStepBuilder(new StepBuilder("childJob2"))
.job(jobNestedDemoJob2()) // 指定要嵌套的子作业
.launcher(launcher) // 指定作业启动器
.repository(jobRepository) // 指定作业仓库
.transactionManager(transactionManager) // 指定事务管理器
.build();
}
// 创建 Job 任务
// 需要配置
// spring.batch.job.names=parentJob
@Bean
public Job parentJob(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return jobBuilderFactory.get("parentJob")
.start(childJob1(jobRepository, transactionManager))
.next(childJob2(jobRepository, transactionManager))
.build();
}
}上述代码中,parentJob() 的执行流程为,先执行 childJob1(内部运行 jobNestedDemoJob1),若 childJob1 成功完成,执行 childJob2(内部运行 jobNestedDemoJob2)。