Fix @Conditional for Batch command line runner
Previously it was @ConditionalOnMissingBean(CommandLineRunner.class) which caued obvious problems when user wanted to add an unrelated CLR. Extended feature set so that a JobRegistry can also be used (with spring.batch.job.name) and the whole idea can be switched off with spring.boot.job.enabled.
This commit is contained in:
@@ -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
|
||||
* <code>spring.boot.exec.enabled=false</code>). User can supply a job name to execute on
|
||||
* startup with <code>spring.batch.exec.name=...</code>.
|
||||
*
|
||||
* @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
|
||||
|
||||
@@ -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<Job> 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user