Java Spring Boot 如何运行批处理作业
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23447948/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How Spring Boot run batch jobs
提问by Evgeni Dimitrov
I followed this samplefor Spring Batch with Boot.
我遵循了 Spring Batch with Boot 的这个示例。
When you run the main method the job is executed. This way I can't figure out how one can control the job execution. For example how you schedule a job, or get access to the job execution, or set job parameters.
当您运行 main 方法时,将执行作业。这样我就无法弄清楚如何控制作业执行。例如,您如何安排作业、访问作业执行或设置作业参数。
I tried to register my own JobLauncher
我试图注册我自己的 JobLauncher
@Bean
public JobLauncher jobLauncher(JobRepository jobRepo){
SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher();
simpleJobLauncher.setJobRepository(jobRepo);
return simpleJobLauncher;
}
but when I try to use it in the main method:
但是当我尝试在 main 方法中使用它时:
public static void main(String[] args) {
ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args);
JobLauncher jobLauncher = ctx.getBean(JobLauncher.class);
//try catch removed for readability
jobLauncher.run(ctx.getBean(Job.class), new JobParameters());
}
The job is again executed when the context is loaded and I got JobInstanceAlreadyCompleteException
when I try to run it manually.
Is there a way to prevent the automatic job execution?
JobInstanceAlreadyCompleteException
当我尝试手动运行它时,会在加载上下文时再次执行该作业。有没有办法阻止自动作业执行?
采纳答案by Evgeni Dimitrov
The jobs execution can be prevented by setting
可以通过设置阻止作业执行
spring.batch.job.enabled=false
in application.properties. Or you can use spring.batch.job.names
it takes a comma-delimited list of job names that will be run.
在 application.properties 中。或者您可以使用spring.batch.job.names
它将运行的以逗号分隔的作业名称列表。
Taken from here: how to stop spring batch scheduled jobs from running at first time when executing the code?
回答by dmotta
You can enable the execution of a Job using rest controller POST:
您可以使用 rest 控制器 POST 启用作业的执行:
@RestController
@RequestMapping(value="/job/")
public class JobLauncherController {
private static final Log LOG = LogFactory.getLog(JobLauncherController.class);
@Autowired
private JobLauncher jobLauncher;
@Autowired
private Job job;
@Autowired
private JobRepository jobRepository;
@Autowired
private JobRegistry jobRegistry;
@RequestMapping("/launchjob/{jobName}")
public String handle(@PathVariable("jobName") String jobName, @RequestBody Map<String,Object> request) throws Exception {
try {
request.put("timeJobStarted", DateUtil.getDateFormatted(new Date(), DateUtil.DATE_UUUUMMDDHHMMSS));
Map<String,Object> mapMessage = this.enrichJobMessage(request);
Map<String, JobParameter> jobParameters = new HashMap<>();
mapMessage.forEach((k,v)->{
MapperUtil.castParameter(jobParameters, k, v);
});
jobParameters.put(Field.Batch.JOB_INSTANCE_NAME, new JobParameter(jobName));
jobLauncher.run(job, new JobParameters(jobParameters));
assertNotNull(jobRegistry.getJob(job.getName()));
}catch( NoSuchJobException ex){
jobRegistry.register(new ReferenceJobFactory(job));
} catch (Exception e) {
LOG.error(e.getMessage(),e);
}
return "Done";
}
public static void castParameter(Map<String, JobParameter> jobParameters, String k, Object v){
if(v instanceof String){
jobParameters.put(k, new JobParameter((String)v));
}else if(v instanceof Date){
jobParameters.put(k, new JobParameter((Date)v));
}else if(v instanceof Double){
jobParameters.put(k, new JobParameter((Double)v));
}else if(v instanceof Long){
jobParameters.put(k, new JobParameter((Long)v));
}else{
DslJson dslJson = new DslJson<>();
JsonWriter writer = dslJson.newWriter();
try {
dslJson.serialize(writer,v);
jobParameters.put(k, new JobParameter(writer.toString()));
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
}
}
}
}