spring.batch.job.enabled 配置用于启动时是否创建JobLauncherCommandLineRunner, 若spring.batch.job.enabled=true, 则会创建JobLauncherCommandLineRunner实例并且执行。spring.batch.job.enabled=false则不会创建实例。那SpringBoot是如何做到的呢?
首先,如何自动创建JobLauncherCommandLineRunner,在源码中找到BatchAutoConfiguration这个类,然后可以找到jobLauncherCommandLineRunner, 这个方法就是用于创建JobLauncherCommandLineRunner实例。可以看到创建该实例的条件是不存在相同的bean并且spring.batch.job.enabled=true,若不存在spring.batch.job.enabled默认创建。
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(
prefix = "spring.batch.job",
name = {"enabled"},
havingValue = "true",
matchIfMissing = true
)
public JobLauncherCommandLineRunner jobLauncherCommandLineRunner(JobLauncher jobLauncher, JobExplorer jobExplorer) {
JobLauncherCommandLineRunner runner = new JobLauncherCommandLineRunner(jobLauncher, jobExplorer);
String jobNames = this.properties.getJob().getNames();
if (StringUtils.hasText(jobNames)) {
runner.setJobNames(jobNames);
}
return runner;
}
找到了创建bean的地方,那它是如何自动执行的run方法的呢?我们都知道,运行SpringBoot项目,我们可以通过SpringApplication.run(Object source, String… args),在SpringApplication中会执行run方法, run方法中会调用afterRefresh方法,最终会调用callRunners方法,在这里可以看到,默认执行了ApplicationRunner和CommandLineRunner的run方法,而JobLauncherCommandLineRunner正是实现了CommandLineRunner接口。最终执行了JobLauncherCommandLineRunner的run方法。
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
FailureAnalyzers analyzers = null;
this.configureHeadlessProperty();
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
Banner printedBanner = this.printBanner(environment);
context = this.createApplicationContext();
new FailureAnalyzers(context);
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
listeners.finished(context, (Throwable)null);
stopWatch.stop();
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, listeners, (FailureAnalyzers)analyzers, var9);
throw new IllegalStateException(var9);
}
}
protected void afterRefresh(ConfigurableApplicationContext context, ApplicationArguments args) {
this.callRunners(context, args);
}
private void callRunners(ApplicationContext context, ApplicationArguments args) {
List<Object> runners = new ArrayList();
runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
AnnotationAwareOrderComparator.sort(runners);
Iterator var4 = (new LinkedHashSet(runners)).iterator();
while(var4.hasNext()) {
Object runner = var4.next();
if (runner instanceof ApplicationRunner) {
this.callRunner((ApplicationRunner)runner, args);
}
if (runner instanceof CommandLineRunner) {
this.callRunner((CommandLineRunner)runner, args);
}
}
}