diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java index 3ad69bf790..e178a1af53 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java @@ -17,17 +17,22 @@ package org.springframework.boot.autoconfigure.batch; import org.springframework.batch.core.launch.JobLauncher; -import org.springframework.boot.CommandLineRunner; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.ExitCodeGenerator; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.util.StringUtils; /** - * {@link EnableAutoConfiguration Auto-configuration} for Spring Batch. + * {@link EnableAutoConfiguration Auto-configuration} for Spring Batch. By default all + * jobs in the context will be executed on startup (disable this behaviour with + * spring.boot.exec.enabled=false). User can supply a job name to execute on + * startup with spring.batch.exec.name=.... * * @author Dave Syer */ @@ -35,6 +40,9 @@ import org.springframework.context.annotation.Configuration; @ConditionalOnClass({ JobLauncher.class }) public class BatchAutoConfiguration { + @Value("${spring.batch.job.name:}") + private String jobName; + @Bean @ConditionalOnMissingBean(BatchDatabaseInitializer.class) public BatchDatabaseInitializer batchDatabaseInitializer() { @@ -42,10 +50,15 @@ public class BatchAutoConfiguration { } @Bean - @ConditionalOnMissingBean(CommandLineRunner.class) + @ConditionalOnMissingBean(JobLauncherCommandLineRunner.class) @ConditionalOnBean(JobLauncher.class) + @ConditionalOnExpression("${spring.batch.job.enabled:true}") public JobLauncherCommandLineRunner jobLauncherCommandLineRunner() { - return new JobLauncherCommandLineRunner(); + JobLauncherCommandLineRunner runner = new JobLauncherCommandLineRunner(); + if (StringUtils.hasText(this.jobName)) { + runner.setJobName(this.jobName); + } + return runner; } @Bean diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/JobLauncherCommandLineRunner.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/JobLauncherCommandLineRunner.java index 8c5d7e03e3..1ad46f7dc3 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/JobLauncherCommandLineRunner.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/JobLauncherCommandLineRunner.java @@ -26,6 +26,8 @@ import org.apache.commons.logging.LogFactory; import org.springframework.batch.core.Job; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobExecutionException; +import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.configuration.JobRegistry; import org.springframework.batch.core.converter.DefaultJobParametersConverter; import org.springframework.batch.core.converter.JobParametersConverter; import org.springframework.batch.core.launch.JobLauncher; @@ -34,10 +36,13 @@ import org.springframework.boot.CommandLineRunner; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.stereotype.Component; +import org.springframework.util.PatternMatchUtils; import org.springframework.util.StringUtils; /** - * {@link CommandLineRunner} to {@link JobLauncher launch} Spring Batch jobs. + * {@link CommandLineRunner} to {@link JobLauncher launch} Spring Batch jobs. Runs all + * jobs in the surrounding context by default. Can also be used to launch a specific job + * by providing a jobName * * @author Dave Syer */ @@ -53,11 +58,20 @@ public class JobLauncherCommandLineRunner implements CommandLineRunner, @Autowired private JobLauncher jobLauncher; + @Autowired(required = false) + private JobRegistry jobRegistry; + + private String jobName; + @Autowired(required = false) private Collection jobs = Collections.emptySet(); private ApplicationEventPublisher publisher; + public void setJobName(String jobName) { + this.jobName = jobName; + } + @Override public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { this.publisher = publisher; @@ -71,12 +85,36 @@ public class JobLauncherCommandLineRunner implements CommandLineRunner, protected void launchJobFromProperties(Properties properties) throws JobExecutionException { - for (Job job : this.jobs) { - JobExecution execution = this.jobLauncher.run(job, - this.converter.getJobParameters(properties)); + JobParameters jobParameters = this.converter.getJobParameters(properties); + executeRegisteredJobs(jobParameters); + executeLocalJobs(jobParameters); + } + + private void executeRegisteredJobs(JobParameters jobParameters) + throws JobExecutionException { + if (this.jobRegistry != null && StringUtils.hasText(this.jobName)) { + Job job = this.jobRegistry.getJob(this.jobName); + JobExecution execution = this.jobLauncher.run(job, jobParameters); if (this.publisher != null) { this.publisher.publishEvent(new JobExecutionEvent(execution)); } } } + + private void executeLocalJobs(JobParameters jobParameters) + throws JobExecutionException { + for (Job job : this.jobs) { + if (StringUtils.hasText(this.jobName)) { + if (!PatternMatchUtils.simpleMatch(this.jobName, job.getName())) { + logger.debug("Skipped job: " + job.getName()); + continue; + } + } + JobExecution execution = this.jobLauncher.run(job, jobParameters); + if (this.publisher != null) { + this.publisher.publishEvent(new JobExecutionEvent(execution)); + } + } + } + } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java index b1ef393864..63098e1366 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationTests.java @@ -36,6 +36,7 @@ import org.springframework.batch.core.job.AbstractJob; import org.springframework.batch.core.launch.JobLauncher; import org.springframework.batch.core.repository.JobRepository; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; import org.springframework.boot.TestUtils; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; @@ -91,6 +92,18 @@ public class BatchAutoConfigurationTests { "job", new JobParameters())); } + @Test + public void testDisableLaunchesJob() throws Exception { + this.context = new AnnotationConfigApplicationContext(); + TestUtils.addEnviroment(this.context, "spring.batch.job.enabled:false"); + this.context.register(JobConfiguration.class, BatchAutoConfiguration.class, + EmbeddedDataSourceConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + this.context.refresh(); + assertNotNull(this.context.getBean(JobLauncher.class)); + assertEquals(0, this.context.getBeanNamesForType(CommandLineRunner.class).length); + } + @Test public void testDisableSchemaLoader() throws Exception { this.context = new AnnotationConfigApplicationContext();