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

Spring Batch传递Job Parameter时任务执行两次的解决咨询

Spring Batch任务执行两次问题的解决方法

问题原因

你的任务之所以执行两次,核心原因是**Spring Boot的Spring Batch自动配置组件JobLauncherCommandLineRunner**会在应用启动时自动检测并运行上下文里的所有Job(无参数),而你自己实现的CommandLineRunner又手动触发了一次带参数的Job执行,两者叠加导致重复运行。


解决方案

方法一:禁用自动触发Job的配置

最直接的解决方式是在配置文件中关闭Spring Batch的自动运行机制:
在application.properties中添加:

spring.batch.job.enabled=false

或者在application.yml中添加:

spring:
  batch:
    job:
      enabled: false

配置生效后,Spring Boot不会自动执行Job,只会运行你在CommandLineRunner中手动启动的带参数任务。

方法二:利用自动运行机制传递参数

如果不想自己实现CommandLineRunner,可以直接通过命令行参数传递Job参数,让JobLauncherCommandLineRunner自动处理:
启动应用时传入参数:

java -jar your-app.jar --message=MyHello --date=2022-09-03 --time=1662209143110

此时组件会自动将这些参数转换为JobParameters并执行Job,避免重复触发。


代码优化建议

你的JobConfiguration中,step1方法直接调用helloWorldTasklet(null)的写法不够规范(@StepScope的Bean应该由Spring容器管理),建议修改为:

@Bean
public Step step1(Tasklet helloWorldTasklet) {
    return stepBuilderFactory.get("step1").tasklet(helloWorldTasklet).build();
}

这样Spring会正确注入@StepScope的Tasklet实例,避免潜在的作用域问题。


修改后的完整示例代码

JobParametersApplication

@EnableBatchProcessing
@SpringBootApplication
public class JobParametersApplication implements CommandLineRunner {
    @Autowired
    private JobLauncher jobLauncher;

    @Autowired
    private Job job;

    public static void main(String[] args) {
        SpringApplication.run(JobParametersApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        JobParameters jobParameters = new JobParametersBuilder()
                .addString("message", "MyHello")
                .addDate("date", new Date())
                .addLong("time", System.currentTimeMillis())
                .toJobParameters(); 

        JobExecution execution = jobLauncher.run(job, jobParameters);
        System.out.println("STATUS :: "+execution.getStatus());
    }
}

JobConfiguration

@Configuration
public class JobConfiguration {
    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    @StepScope
    public Tasklet helloWorldTasklet(@Value("#{jobParameters['message']}") String message) {
        return (stepContribution, chunkContext) -> {
            System.out.println(message);
            return RepeatStatus.FINISHED;
        };
    }

    @Bean
    public Step step1(Tasklet helloWorldTasklet) {
        return stepBuilderFactory.get("step1").tasklet(helloWorldTasklet).build();
    }

    @Bean
    public Job jobParametersJob() {
        return jobBuilderFactory.get("jobParametersJob").start(step1()).build();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 09:54:33