英文:
How can I pass Batch Job parameters to my batch job without using CommandLineRuner?
问题
我有一个Spring批处理作业,应该在Spring Boot应用程序启动时运行,而且Spring Boot应用程序必须在批处理作业完成后立即关闭。
我通过在application.yml文件中使用spring.batch.job.enabled = true
属性来覆盖上述情况。
一开始它运行得很好,但自从最近几次运行以来,我一直在收到以下错误:
> org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException:已存在作业实例,并且对参数={}已经完成。如果要再次运行此作业,请更改参数。
现在,我不想使用CommandLineRunner,它本来可以让我在使用JobLauncher运行作业时传递JobParameters。这个批处理作业将在容器内运行,应该在容器运行时立即触发。
我的批处理作业应该在Spring Boot应用程序运行时立即运行,并且一旦批处理作业完成,应用程序必须关闭。
我不确定是否可以在不使用CommandLineRunner的情况下传递Job参数。如果可以的话,有人可以指导我正确的方向吗?
我的BatchConfiguration如下:
@Configuration
@EnableBatchProcessing
@Component
public class BatchConfiguration {
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Autowired
JobRepository jobRepository;
@Bean
public JobLauncher asyncJobLauncher() throws Exception {
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
jobLauncher.setJobRepository(jobRepository);
jobLauncher.setTaskExecutor(new SimpleAsyncTaskExecutor());
jobLauncher.afterPropertiesSet();
return jobLauncher;
}
@Bean
public Job loadDataFromIodsIcOutbound(DataListener listener, Step inboundStep) {
return jobBuilderFactory.get("jobName")
.incrementer(new RunIdIncrementer())
.listener(listener)
.flow(inboundStep)
.end()
.build();
}
}
希望这对你有所帮助。
英文:
I have a spring batch job which should run at the start up of spring boot app and spring boot app must shut down as soon as the batch job finishes.
I have covered the above scenario by using spring.batch.job.enabled = true
property in application.yml file.
It ran fine in the starting but since few last runs I am getting below error:
>org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException: A job instance already exists and is complete for parameters={}. If you want to run this job again, change the parameters.
Now, I don't want to use CommandLineRunner which would have let me pass the JobParameters while running the job using JobLauncher. This batch job will run with in a container and should get triggered as soon as the container runs.
My batch job should run as soon as the spring boot apps runs and the app must shut down once the batch job finishes.
I am not sure if I can pass the Job parameters without using CommandLineRunner or not. If I can, can someone point me to the right direction?
My BatchConfiguration looks like this:
@Configuration
@EnableBatchProcessing
@Component
public class BatchConfiguration{
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Autowired
JobRepository jobRepository;
@Bean
public JobLauncher asyncJobLauncher() throws Exception {
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
jobLauncher.setJobRepository(jobRepository);
jobLauncher.setTaskExecutor(new SimpleAsyncTaskExecutor());
jobLauncher.afterPropertiesSet();
return jobLauncher;
}
@Bean
public Job loadDataFromIodsIcOutbound(DataListener listener, Step inboundStep) {
return jobBuilderFactory.get("jobName")
.incrementer(new RunIdIncrementer())
.listener(listener)
.flow(inboundStep)
.end()
.build();
}
</details>
# 答案1
**得分**: 1
这则消息说:
> 作业实例已经存在并且已经完成
这不是错误。这意味着您的作业已经执行并且成功完成。这是Spring Batch作业的默认行为,应该防止在不更改任何参数的情况下多次运行作业。
如果您的用例不同,您想要能够再次启动相同的作业,那么您可以通过在步骤构建器中添加以下行来更改此默认设置:
.allowStartIfComplete(true)
要以编程方式使用特定参数启动Spring Batch作业,可以按照以下步骤操作:
1. 禁用自动启动
spring.batch.job.enabled=false
2. 实现ApplicationRunner并添加作业参数
@SpringBootApplication
public class BatchApplication implements ApplicationRunner {
@Autowired
JobLauncher jobLauncher;
@Autowired
Job job;
@Override
public void run(ApplicationArguments args) throws Exception {
log.info("Spring Batch starting.");
JobParameters params = new JobParametersBuilder()
.addString("jobName", "MyJobName")
.addLocalDateTime("currentTime", LocalDateTime.now())
.toJobParameters();
jobLauncher.run(job, params);
log.info("Spring Batch done.");
}
public static void main(String[] args) {
SpringApplication.run(BatchApplication.class, args);
}
}
这样,您的Spring应用程序将使用指定的参数运行批处理,然后退出。(假设它没有依赖于Spring Web、MVC或计划作业,否则它将继续运行)。
<details>
<summary>英文:</summary>
The messages says:
> A job instance already exists and is complete
It is not an error. It means only that your job has been already executed and was successful. This is the default behavior of a Spring Batch job and should prevent running jobs more then once without changing any parameters.
If your use case is different and you want be able to start the same job again then you can change this default setting by adding this line to your step builder:
.allowStartIfComplete(true)
To start the Spring Batch job programmatically with specific parameters you can follow this steps:
1. disable automatic start
spring.batch.job.enabled=false
2. implement ApplicationRunner and add your job parameters
@SpringBootApplication
public class BatchApplication implements ApplicationRunner {
@Autowired
JobLauncher jobLauncher;
@Autowired
Job job;
@Override
public void run(ApplicationArguments args) throws Exception {
log.info("Spring Batch starting.");
JobParameters params = new JobParametersBuilder()
.addString("jobName", "MyJobName")
.addLocalDateTime("currentTime", LocalDateTime.now())
.toJobParameters();
jobLauncher.run(job, params);
log.info("Spring Batch done.");
}
public static void main(String[] args) {
SpringApplication.run(BatchApplication.class, args);
}
}
This way you Spring Application will run the batch with specified parameters and exit. (Assuming it has no dependencies to Spring Web or MVC or scheduled jobs in which cases it will continue running).
</details>
# 答案2
**得分**: 1
你可以将作业参数作为键值对传递到你的Spring Boot应用程序的命令行上:
```java -jar myjob.jar name=foo```
<details>
<summary>英文:</summary>
> I am not sure if I can pass the Job parameters without using CommandLineRunner or not. If I can, can someone point me to the right direction?
You can pass job parameters to your spring boot app on the command line as key/value pairs:
java -jar- myjob.jar name=foo
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论