Spring Boot Batch 2.7.1迁3.2.10遇多Job指定名称错误求助
问题:Spring Boot Batch 3.2.10 多Job启动报错
将Spring Boot Batch应用从2.7.1版本迁移至3.2.10版本后,启动时抛出如下错误:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jobLauncherApplicationRunner' defined in class path resource [org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.class]: Job name must be specified in case of multiple jobs at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1806) ~[spring-beans-6.1.13.jar:6.1.13] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600) ~[spring-beans-6.1.13.jar:6.1.13] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[spring-beans-6.1.13.jar:6.1.13] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337) ~[spring-beans-6.1.13.jar:6.1.13] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.13.jar:6.1.13] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335) ~[spring-beans-6.1.13.jar:6.1.13] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.1.13.jar:6.1.13] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975) ~[spring-beans-6.1.13.jar:6.1.13] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:971) ~[spring-context-6.1.13.jar:6.1.13] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:625) ~[spring-context-6.1.13.jar:6.1.13] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-3.2.10.jar:3.2.10] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) ~[spring-boot-3.2.10.jar:3.2.10] at org.springframework.boot.SpringApplication.run(SpringApplication.java:335) ~[spring-boot-3.2.10.jar:3.2.10] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363) ~[spring-boot-3.2.10.jar:3.2.10] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352) ~[spring-boot-3.2.10.jar:3.2.10] at com.example.demo.Application.main(Application.java:11) ~[classes/:na] Caused by: java.lang.IllegalArgumentException: Job name must be specified in case of multiple jobs at org.springframework.util.Assert.isTrue(Assert.java:111) ~[spring-core-6.1.13.jar:6.1.13] at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.afterPropertiesSet(JobLauncherApplicationRunner.java:115) ~[spring-boot-autoconfigure-3.2.10.jar:3.2.10] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1853) ~[spring-beans-6.1.13.jar:6.1.13] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1802) ~[spring-beans-6.1.13.jar:6.1.13] ... 15 common frames omitted Process finished with exit code 1
相关代码
ChildJobConfig.java
package com.example.demo; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; import org.springframework.batch.core.job.builder.JobBuilder; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.step.builder.StepBuilder; 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; @Configuration public class ChildJobConfiguration { @Autowired private JobRepository jobRepository; @Autowired private PlatformTransactionManager transactionManager; @Bean public Step step1a() { return new StepBuilder("step1a", jobRepository) .tasklet((contribution, chunkContext) -> { System.out.println("\t>>This is step 1a"); return RepeatStatus.FINISHED; }, transactionManager).build(); } @Bean public Job childJob() { return new JobBuilder("childJob", jobRepository) .start(step1a()) .build(); } }
ParentJobConfig.java
package com.example.demo; import org.springframework.batch.core.Job; import org.springframework.batch.core.Step; import org.springframework.batch.core.job.builder.JobBuilder; import org.springframework.batch.core.launch.JobLauncher; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.step.builder.JobStepBuilder; import org.springframework.batch.core.step.builder.StepBuilder; 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; @Configuration public class ParentJobConfiguration { @Autowired private JobRepository jobRepository; @Autowired private PlatformTransactionManager transactionManager; @Autowired private Job childJob; @Autowired private JobLauncher jobLauncher; @Bean public Step step1() { return new StepBuilder("step1", jobRepository) .tasklet((contribution, chunkContext) -> { System.out.println(">> This is step 1"); return RepeatStatus.FINISHED; }, transactionManager).build(); } @Bean public Job parentJob(JobRepository jobRepository, PlatformTransactionManager transactionManager) { Step childJobStep = new JobStepBuilder(new StepBuilder("childJobStep", jobRepository)) .job(childJob) .launcher(jobLauncher) .build(); return new JobBuilder("parentJob", jobRepository) .start(step1()) .next(childJobStep) .build(); } }
MainApp.java
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
application.properties
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=root spring.datasource.schema=schema-mysql.sql spring.batch.job.names=parentJob
解决方案
修正配置属性名称:Spring Boot 3.x 中
spring.batch.job.names已被废弃,替代为单数形式的spring.batch.job.name。修改application.properties配置:spring.batch.job.name=parentJob旧复数属性在新版本中无法被正确识别,导致自动配置的
JobLauncherApplicationRunner无法获取指定Job,触发多Job校验失败。标记子Job为非自动启动:如果子Job仅作为父Job的步骤执行,无需单独启动,可在子Job的Bean定义中设置禁止自动启动:
@Bean public Job childJob() { return new JobBuilder("childJob", jobRepository) .start(step1a()) .build(); }配合
spring.batch.job.name=parentJob,确保只有父Job被自动执行。禁用自动Job启动:如果不需要应用启动时自动执行Job,可直接关闭自动启动功能:
spring.batch.job.enabled=false之后可手动注入
JobLauncher和Job按需启动任务。手动配置JobLauncherApplicationRunner:绕过自动配置,手动创建Runner并绑定指定Job:
@Bean public JobLauncherApplicationRunner jobLauncherApplicationRunner(JobLauncher jobLauncher, Job parentJob) { JobLauncherApplicationRunner runner = new JobLauncherApplicationRunner(); runner.setJobLauncher(jobLauncher); runner.setJob(parentJob); return runner; }
内容的提问来源于stack exchange,提问作者PAA
相关产品推荐
相关产品推荐

