You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Batch 5作业无法自动启动问题求助(Spring Boot 3升级)

问题描述

将作业从Spring Boot 2升级到Spring Boot 3,同步升级Spring Batch至5版本后,作业不再自动启动。该作业以jar包形式运行(非定时/异步作业),此前Spring Boot 2版本使用以下命令可正常启动:

java -jar MyJobApp.jar --batch.input-file="/path/to/file/filename.xml" --spring.config.additional-location=file:/path/to/config/externalPropertyFile.yml

核心需求

  • 自定义数据库表记录作业状态,不需要Spring Batch默认元数据表,希望将Batch元数据存入内存数据库,通过JobListener持久化自定义数据。
  • 已尝试@EnableBatchProcessing声明式配置、继承DefaultBatchConfigurer重写getDataSource和getTransactionManager,也知道可以用CommandLineRunner结合JobLauncher手动启动,但认为这不是正确方式。
  • 集成测试中通过JobLauncherTestUtils使用SimpleJobLauncher可正常运行作业。

当前配置

  1. 主应用类:
@EnableConfigurationProperties(BatchProps::class, WebClientProps::class)
@SpringBootApplication
class MyJobApp

fun main(args: Array<String>) {
    exitProcess(SpringApplication.exit(runApplication<MyJobApp>(*args)))
}
  1. application.yml配置:
spring:
  main:
    web-application-type: none
  application:
    name: MyJobApp
  batch:
    job:
      enabled: true
  1. Batch配置类:
@Configuration
@EnableBatchProcessing(dataSourceRef = "batchDataSource", transactionManagerRef = "batchTransactionManager")
class BatchConfig(
    private val reader: PackageDataReader,
    private val processor: PackageDataProcessor,
    private val writer: OrderWriter,
) {

    @Bean
    fun job(listener: JobNotificationListener,
            jobRepository: JobRepository,
            transactionManager: PlatformTransactionManager,
            ioStep: Step): Job = JobBuilder(JOB_NAME, jobRepository)
        .listener(listener)
        .flow(ioStep)
        .end()
        .build()


    @Bean
    fun ioStep(jobRepository: JobRepository, transactionManager: PlatformTransactionManager): Step = StepBuilder(STEP_NAME, jobRepository)
        .chunk<PackageData, List<OrderType>>(1, transactionManager)
        .reader(reader)
        .processor(processor)
        .writer(writer)
        .build()

    // 避免Spring Batch元数据表写入业务DB,使用内存H2存储
    @Bean
    fun batchDataSource(): DataSource {
        return EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2)
            .addScript("/org/springframework/batch/core/schema-h2.sql")
            .generateUniqueName(true).build()
    }

    @Bean
    fun batchTransactionManager(): JdbcTransactionManager? {
        return JdbcTransactionManager(batchDataSource())
    }
}

作业运行日志

2023-03-03T11:17:05.041+01:00 DEBUG 20592 --- [           main] MyJobApp : Running with Spring Boot v3.0.2, Spring v6.0.4
2023-03-03T11:17:05.041+01:00  INFO 20592 --- [           main] MyJobApp : The following 1 profile is active: "dev"
2023-03-03T11:17:05.611+01:00  INFO 20592 --- [           main] o.s.b.c.c.annotation.BatchRegistrar      : Finished Spring Batch infrastructure beans configuration in 6 ms.
2023-03-03T11:17:07.133+01:00  INFO 20592 --- [           main] o.s.j.d.e.EmbeddedDatabaseFactory        : Starting embedded database: url='jdbc:h2:mem:3df4e81c-eff0-45fc-a9f2-9b97f721b113;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false', username='sa'
2023-03-03T11:17:07.433+01:00  INFO 20592 --- [           main] o.s.b.c.r.s.JobRepositoryFactoryBean     : No database type set, using meta data indicating: H2
2023-03-03T11:17:07.499+01:00  INFO 20592 --- [           main] .c.a.BatchObservabilityBeanPostProcessor : No Micrometer observation registry found, defaulting to ObservationRegistry.NOOP
2023-03-03T11:17:07.513+01:00  INFO 20592 --- [           main] .c.a.BatchObservabilityBeanPostProcessor : No Micrometer observation registry found, defaulting to ObservationRegistry.NOOP
2023-03-03T11:17:07.519+01:00  INFO 20592 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : No TaskExecutor has been set, defaulting to synchronous executor.
2023-03-03T11:17:07.743+01:00  INFO 20592 --- [           main] MyJobbApp : Started MyJobApp in 3.28 seconds (process running for 4.247)
2023-03-03T11:17:07.755+01:00  INFO 20592 --- [           main] o.s.j.d.e.EmbeddedDatabaseFactory        : Shutting down embedded database: url='jdbc:h2:mem:3df4e81c-eff0-45fc-a9f2-9b97f721b113;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false'
Process finished with exit code 0
解决方案

核心原因

Spring Batch 5中,当使用@EnableBatchProcessing或继承DefaultBatchConfiguration时,Spring Boot的Batch自动配置会完全后退,不再自动触发作业启动逻辑。这就是作业不自动运行的根本原因。

解决步骤

方式一:保留@EnableBatchProcessing,手动恢复自动启动逻辑

如果需要自定义JobRepository的数据源(内存H2),同时希望保留自动启动行为,可以添加JobLauncherApplicationRunner Bean,它是Spring Boot原生的Batch作业自动启动组件:

在BatchConfig中添加以下代码:

@Bean
fun jobLauncherApplicationRunner(jobLauncher: JobLauncher, job: Job, args: Array<String>): JobLauncherApplicationRunner {
    val runner = JobLauncherApplicationRunner(jobLauncher, job)
    // 解析命令行参数构建JobParameters
    val params = JobParametersBuilder()
    args.forEach { arg ->
        if (arg.startsWith("--batch.input-file=")) {
            val filePath = arg.substringAfter("--batch.input-file=")
            params.addString("inputFile", filePath)
        }
        // 可添加其他需要的参数
    }
    runner.setJobParameters(params.toJobParameters())
    return runner
}

方式二:移除@EnableBatchProcessing,利用自动配置扩展自定义数据源

这种方式更贴合Spring Boot的自动配置理念,不需要手动处理作业启动逻辑,推荐使用:

  1. 移除BatchConfig上的@EnableBatchProcessing注解
  2. 将Batch专属的数据源和事务管理器Bean名称改为springBatchDataSource和springBatchTransactionManager——Spring Boot自动配置会自动识别这两个名称的Bean作为Batch的专属资源:
@Configuration
class BatchConfig(
    private val reader: PackageDataReader,
    private val processor: PackageDataProcessor,
    private val writer: OrderWriter,
) {
    // 原job和ioStep Bean保留不变

    @Bean
    fun springBatchDataSource(): DataSource {
        return EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2)
            .addScript("/org/springframework/batch/core/schema-h2.sql")
            .generateUniqueName(true).build()
    }

    @Bean
    fun springBatchTransactionManager(): JdbcTransactionManager {
        return JdbcTransactionManager(springBatchDataSource())
    }
}

修改后,spring.batch.job.enabled=true的配置会正常生效,作业会自动启动,同时元数据会存入你定义的内存H2数据库。

验证说明

  • 两种方式都能确保Batch元数据不会写入业务数据库
  • 集成测试中JobLauncherTestUtils的使用不受配置变更影响
  • 方式二无需额外编写启动逻辑,维护成本更低

内容的提问来源于stack exchange,提问作者StackCanary

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 22:02:12