当我创建 Spring Batch 多个 JobBuild 时发生错误

kot*_*eek 2 spring spring-batch kotlin spring-boot

我正在使用 kotlin、spring boot 3.0.1 和 batch 。我创建了两个作业/步骤配置。但是当我构建项目时,我看到了以下错误。我问一个问题是因为很难将以前的批处理示例更改为最新版本。有人解决这个问题了吗?奇怪的是,如果你在配置上删除一项工作,它就可以运行它。

错误

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2023-01-03T13:47:34.101+09:00 ERROR 68470 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jobLauncherApplicationRunner': Invocation of init method failed
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:195) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:420) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1743) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:961) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:915) ~[spring-context-6.0.3.jar:6.0.3]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584) ~[spring-context-6.0.3.jar:6.0.3]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730) ~[spring-boot-3.0.1.jar:3.0.1]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432) ~[spring-boot-3.0.1.jar:3.0.1]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-3.0.1.jar:3.0.1]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302) ~[spring-boot-3.0.1.jar:3.0.1]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291) ~[spring-boot-3.0.1.jar:3.0.1]
    at com.linetest.batch.SpringBatchApplicationKt.main(SpringBatchApplication.kt:15) ~[main/:na]
Caused by: java.lang.IllegalArgumentException: Job name must be specified in case of multiple jobs
    at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.validate(JobLauncherApplicationRunner.java:116) ~[spring-boot-autoconfigure-3.0.1.jar:3.0.1]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:424) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:368) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:192) ~[spring-beans-6.0.3.jar:6.0.3]
    ... 17 common frames omitted

Run Code Online (Sandbox Code Playgroud)

配置/SingleStepJobConfig.kt

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2023-01-03T13:47:34.101+09:00 ERROR 68470 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jobLauncherApplicationRunner': Invocation of init method failed
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:195) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:420) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1743) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:961) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:915) ~[spring-context-6.0.3.jar:6.0.3]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584) ~[spring-context-6.0.3.jar:6.0.3]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730) ~[spring-boot-3.0.1.jar:3.0.1]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432) ~[spring-boot-3.0.1.jar:3.0.1]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-3.0.1.jar:3.0.1]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302) ~[spring-boot-3.0.1.jar:3.0.1]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291) ~[spring-boot-3.0.1.jar:3.0.1]
    at com.linetest.batch.SpringBatchApplicationKt.main(SpringBatchApplication.kt:15) ~[main/:na]
Caused by: java.lang.IllegalArgumentException: Job name must be specified in case of multiple jobs
    at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.validate(JobLauncherApplicationRunner.java:116) ~[spring-boot-autoconfigure-3.0.1.jar:3.0.1]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:424) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:368) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:192) ~[spring-beans-6.0.3.jar:6.0.3]
    ... 17 common frames omitted

Run Code Online (Sandbox Code Playgroud)

配置/MultipleStepJobConfig.kt


import com.linetest.batch.tasklet.SimpleTasklet
import mu.KotlinLogging
import org.springframework.batch.core.Job
import org.springframework.batch.core.Step
import org.springframework.batch.core.StepContribution
import org.springframework.batch.core.job.builder.JobBuilder
import org.springframework.batch.core.repository.JobRepository
import org.springframework.batch.core.scope.context.ChunkContext
import org.springframework.batch.core.step.builder.StepBuilder
import org.springframework.batch.repeat.RepeatStatus
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.transaction.PlatformTransactionManager

private val log = KotlinLogging.logger {}

@Configuration
class SingleStepJobConfig(
    private val transactionManager: PlatformTransactionManager,
    private val jobRepository: JobRepository,
) {

    @Bean
    fun singleStepJob(): Job {
        return JobBuilder("singleStepJob", jobRepository)
            .start(singleStep())
            .build()
    }


    @Bean
    fun singleStep(): Step {
        return StepBuilder("singleStep", jobRepository)
            .tasklet(myTaskletAsBean(), transactionManager)
            .build()
    }

    @Bean
    fun singleStep2(): Step {
        return StepBuilder("singleStep2", jobRepository)
            .tasklet({
                    _: StepContribution,
                    _: ChunkContext ->
                log.info { "single step2 tasklet 2 test" }
                RepeatStatus.FINISHED
            }, transactionManager)
            .build()
    }

    @Bean
    fun myTaskletAsBean(): SimpleTasklet {
        val simpleTasklet = SimpleTasklet()
        simpleTasklet.setValue("Single Step Job Properties Setup!!!<<--")

        return simpleTasklet
    }

}

Run Code Online (Sandbox Code Playgroud)

小任务/SimpleTasklet.kt


import com.linetest.batch.tasklet.SimpleTasklet
import mu.KotlinLogging
import org.apache.logging.log4j.util.Strings
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.EnableBatchProcessing
import org.springframework.batch.core.job.builder.JobBuilder
import org.springframework.batch.core.repository.JobRepository
import org.springframework.batch.core.scope.context.ChunkContext
import org.springframework.batch.core.step.builder.StepBuilder
import org.springframework.batch.repeat.RepeatStatus
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.batch.BatchProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.transaction.PlatformTransactionManager

private val log = KotlinLogging.logger {}

@Configuration
class MultipleStepJobConfig(
    private val transactionManager: PlatformTransactionManager,
    private val jobRepository: JobRepository,
) {

    @Bean
    fun multipleStepJob(): Job {
        return JobBuilder("multipleStepJob", jobRepository)
            .start(startStep())
            .next(processStep())
            .next(writeStep())
            .build()
    }

    @Bean
    fun startStep(): Step {
        return StepBuilder("startStep", jobRepository)
            .tasklet({
                     _: StepContribution,
                    _: ChunkContext ->
                log.info { "multiple Step Start" }
                RepeatStatus.FINISHED
            }, transactionManager)
            .build()
    }



    @Bean
    fun processStep(): Step {
        return StepBuilder("processStep", jobRepository)
            .tasklet({_: StepContribution,
                      _: ChunkContext ->
                log.info { "Execute processStep >>>>" }
                RepeatStatus.FINISHED
            }, transactionManager)
            .build()
    }

    @Bean
    fun writeStep(): Step {
        return StepBuilder("writeStep", jobRepository)
            .tasklet({_: StepContribution,
                      _: ChunkContext ->
                log.info { "Execute writeStep >>>>" }
                RepeatStatus.FINISHED
            }, transactionManager)
            .build()
    }



}

Run Code Online (Sandbox Code Playgroud)

SpringBatchApplication.kt

import mu.KotlinLogging
import org.springframework.batch.core.StepContribution
import org.springframework.batch.core.configuration.annotation.StepScope
import org.springframework.batch.core.scope.context.ChunkContext
import org.springframework.batch.core.step.tasklet.Tasklet
import org.springframework.batch.repeat.RepeatStatus
import org.springframework.beans.factory.InitializingBean
import org.springframework.stereotype.Component

private val log = KotlinLogging.logger {  }

@Component
@StepScope
class SimpleTasklet : Tasklet, InitializingBean {
    private var resource: String? = null

    @Throws(Exception::class)
    override fun execute(
        contribution: StepContribution,
        chunkContext: ChunkContext
    ): RepeatStatus? {
        log.info { "Execute SimpleTasklet >>>>" }
        return RepeatStatus.FINISHED
    }

    fun setValue(text:String){
        this.resource = text
        log.info { "$resource"}
    }

    @Throws(Exception::class)
    override fun afterPropertiesSet() {
        log.info { "AfterPropertiesSet" }
    }

}

Run Code Online (Sandbox Code Playgroud)

奇怪的是,如果你在配置上删除一项工作,它就可以运行它。

现有示例可以运行。参考号 https://www.devkuma.com/docs/spring-batch/start/

结果 Spring Boot 2.5.5

2023-01-04 00:05:48.365  INFO 7829 --- [           main] com.linetest.batch.BatchApplicationKt    : Starting BatchApplicationKt using Java 17.0.5 on mC02YR40ALVDL with PID 7829 (/Users/ParkJiho/Documents/workspace/kotlin/spring-batch-test-0102/build/classes/kotlin/main started by ParkJiho in /Users/ParkJiho/Documents/workspace/kotlin/spring-batch-test-0102)
2023-01-04 00:05:48.366  INFO 7829 --- [           main] com.linetest.batch.BatchApplicationKt    : No active profile set, falling back to default profiles: default
2023-01-04 00:05:49.267  INFO 7829 --- [           main] c.linetest.batch.tasklet.SimpleTasklet   : TESTTESTTEST  has been set!!!!!!!!!!1
2023-01-04 00:05:49.267  INFO 7829 --- [           main] c.linetest.batch.tasklet.SimpleTasklet   : AfterPropertiesSet
2023-01-04 00:05:49.282  INFO 7829 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2023-01-04 00:05:49.433  INFO 7829 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2023-01-04 00:05:49.538  INFO 7829 --- [           main] o.s.b.c.r.s.JobRepositoryFactoryBean     : No database type set, using meta data indicating: H2
2023-01-04 00:05:49.665  INFO 7829 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : No TaskExecutor has been set, defaulting to synchronous executor.
2023-01-04 00:05:49.722  INFO 7829 --- [           main] com.linetest.batch.BatchApplicationKt    : Started BatchApplicationKt in 1.659 seconds (JVM running for 2.351)
2023-01-04 00:05:49.723  INFO 7829 --- [           main] o.s.b.a.b.JobLauncherApplicationRunner   : Running default command line with: []
2023-01-04 00:05:49.766  INFO 7829 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [FlowJob: [name=flowStepJob]] launched with the following parameters: [{}]
2023-01-04 00:05:49.799  INFO 7829 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [flowStartStep]
2023-01-04 00:05:49.806  INFO 7829 --- [           main] c.l.batch.config.FlowStepJobConfig       : Flow Start Step!!<------
2023-01-04 00:05:49.811  INFO 7829 --- [           main] o.s.batch.core.step.AbstractStep         : Step: [flowStartStep] executed in 12ms
2023-01-04 00:05:49.816  INFO 7829 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [flowProcessStep]
2023-01-04 00:05:49.818  INFO 7829 --- [           main] c.l.batch.config.FlowStepJobConfig       : flowProcessStep
2023-01-04 00:05:49.819  INFO 7829 --- [           main] o.s.batch.core.step.AbstractStep         : Step: [flowProcessStep] executed in 3ms
2023-01-04 00:05:49.823  INFO 7829 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [flowWriteStep]
2023-01-04 00:05:49.825  INFO 7829 --- [           main] c.l.batch.config.FlowStepJobConfig       : flowWriteStep
2023-01-04 00:05:49.827  INFO 7829 --- [           main] o.s.batch.core.step.AbstractStep         : Step: [flowWriteStep] executed in 3ms
2023-01-04 00:05:49.830  INFO 7829 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [FlowJob: [name=flowStepJob]] completed with the following parameters: [{}] and the following status: [COMPLETED] in 40ms
2023-01-04 00:05:49.833  INFO 7829 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [SimpleJob: [name=multipleStepJob]] launched with the following parameters: [{}]
2023-01-04 00:05:49.837  INFO 7829 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [startStep]
2023-01-04 00:05:49.839  INFO 7829 --- [           main] c.l.batch.config.MultipleStepJobConfig   : Start Step<--------
2023-01-04 00:05:49.841  INFO 7829 --- [           main] o.s.batch.core.step.AbstractStep         : Step: [startStep] executed in 4ms
2023-01-04 00:05:49.844  INFO 7829 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [nextStep]
2023-01-04 00:05:49.846  INFO 7829 --- [           main] c.l.batch.config.MultipleStepJobConfig   : Next Step<--------
2023-01-04 00:05:49.847  INFO 7829 --- [           main] o.s.batch.core.step.AbstractStep         : Step: [nextStep] executed in 3ms
2023-01-04 00:05:49.850  INFO 7829 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [lastStep]
2023-01-04 00:05:49.852  INFO 7829 --- [           main] c.l.batch.config.MultipleStepJobConfig   : Last Step<--------
2023-01-04 00:05:49.853  INFO 7829 --- [           main] o.s.batch.core.step.AbstractStep         : Step: [lastStep] executed in 3ms
2023-01-04 00:05:49.855  INFO 7829 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [SimpleJob: [name=multipleStepJob]] completed with the following parameters: [{}] and the following status: [COMPLETED] in 21ms
2023-01-04 00:05:49.858  INFO 7829 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [SimpleJob: [name=singleStepJob]] launched with the following parameters: [{}]
2023-01-04 00:05:49.861  INFO 7829 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [simpleStep]
2023-01-04 00:05:49.862  INFO 7829 --- [           main] c.linetest.batch.tasklet.SimpleTasklet   : Execute SimpleTasklet >>>>
2023-01-04 00:05:49.864  INFO 7829 --- [           main] o.s.batch.core.step.AbstractStep         : Step: [simpleStep] executed in 3ms
2023-01-04 00:05:49.865  INFO 7829 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [SimpleJob: [name=singleStepJob]] completed with the following parameters: [{}] and the following status: [COMPLETED] in 7ms
2023-01-04 00:05:49.869  INFO 7829 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2023-01-04 00:05:49.871  INFO 7829 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
Run Code Online (Sandbox Code Playgroud)

小智 5

从日志中可以清楚地看出这个问题。

Caused by: java.lang.IllegalArgumentException: Job name must be specified in case of multiple jobs
    at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.validate(JobLauncherApplicationRunner.java:116) ~[spring-boot-autoconfigure-3.0.1.jar:3.0.1]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:424) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:368) ~[spring-beans-6.0.3.jar:6.0.3]
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:192) ~[spring-beans-6.0.3.jar:6.0.3]
    ... 17 common frames omitted

Run Code Online (Sandbox Code Playgroud)

如果 Spring Context 中只存在一个作业,那么 Spring 在启动时默认运行该作业,但如果 Spring Context 中存在多个作业,那么我们需要告诉 Spring 在启动时运行哪个作业。

因此,您可以在文件中指定此属性application.properties,然后重试。

spring.batch.job.name=singleStepJob
Run Code Online (Sandbox Code Playgroud)

或者

spring.batch.job.name=multipleStepJob
Run Code Online (Sandbox Code Playgroud)

或者您可以通过此属性禁用启动时运行的作业,并使用 以编程方式运行作业JobLauncher

spring.batch.job.enabled=false
Run Code Online (Sandbox Code Playgroud)

如何以编程方式运行作业?

public class JobLauncherService {

    private final JobLauncher jobLauncher;
    
    private final Job job;

    @Autowired
    public JobLauncherService(JobLauncher jobLauncher, @Qualifier("multipleStepJob") Job job) {
        this.jobLauncher = jobLauncher;
        this.job = job;
    }

    public void runJob() {
        try {
            final JobExecution jobExecution = jobLauncher.run(job, new JobParameters());
            System.out.println("Job Status : " + jobExecution.getStatus());
            System.out.println("Job completed");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Job failed");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)