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
相关产品推荐
相关产品推荐

