启动篇
在使用SpringBoot时,只需要一行代码就可以启动配置好的SpringBatch应用。
@SpringBootApplication
public class MainClass {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(MainClass.class);
int exitCode = SpringApplication.exit(context );
System.exit(exitCode);
}
}
好奇是如何做到的。
首先SpringBootApplication注解有如下配置:
1.SpringBootConfiguration 中引用了Configuration注解。
2.EnableAutoConfiguration
(1)从环境中读取spring.boot.enableautoconfiguration属性,若为true则开启自动配置。
(2)用beanClassLoader 读取 spring-autoconfigure-metadata.properties
(3) 通过springfactories的方式获取到候选配置,去重,去exclutions
(4) List<String> filter(List<String> configurations, AutoConfigurationMetadata autoConfigurationMetadata)方法过滤不需要的配置
(5)派发AutoConfigurationImportEvent
(6)返回Import列表。
3.ComponentScan
详细内容https://blog.youkuaiyun.com/qq_26000415/article/details/78947283这篇文章说的比较清楚。可以参考。
--------------------
第二部分是SpringApplication中,会调用callRunner方法如下:
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);
for (Object runner : new LinkedHashSet<>(runners)) {
if (runner instanceof ApplicationRunner) {
callRunner((ApplicationRunner) runner, args);
}
if (runner instanceof CommandLineRunner) {
callRunner((CommandLineRunner) runner, args);
}
}
}
这里会获取到SpringBatch 自动配置, BatchAutoConfiguration中注册的CommandLineRunner bean。进而执行。
@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来自定义CommandLineRunner,以此在客户无感知的情况下嵌入自定义行为。
退出篇
参考JobLauncherCommandLineRunner 可知,在execute方法中发布了gApplicationEvent
protected void execute(Job job, JobParameters jobParameters)
throws JobExecutionAlreadyRunningException, JobRestartException,
JobInstanceAlreadyCompleteException, JobParametersInvalidException,
JobParametersNotFoundException {
JobParameters nextParameters = new JobParametersBuilder(jobParameters,
this.jobExplorer).getNextJobParameters(job).toJobParameters();
JobExecution execution = this.jobLauncher.run(job, nextParameters);
if (this.publisher != null) {
this.publisher.publishEvent(new JobExecutionEvent(execution));
}
}
JobExecutionEvent 事件由JobExecutionExitCodeGenerator监听。并以此生成退出码。故可使用开篇代码带状态码地退出应用,以便容器等运行环境感知到异常退出:
@SpringBootApplication
public class MainClass {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(MainClass.class);
int exitCode = SpringApplication.exit(context );
System.exit(exitCode);
}
}