一个最简单的spring batch的程序,照办官网的sample,如下
一个配置程序
@Configuration @EnableBatchProcessing @EnableAutoConfiguration public class BatchConfiguration { @Autowired private JobBuilderFactory jobBuilderFactory; @Autowired private StepBuilderFactory stepBuilderFactory; @Bean public Step step1() { return stepBuilderFactory.get("step1") .tasklet(new Tasklet() { public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) { return null; } }) .build(); } @Bean public Job job(Step step1) throws Exception { return jobBuilderFactory.get("job1") .incrementer(new RunIdIncrementer()) .start(step1) .build(); } }
一个主程序
public class Main { public static void main(String [] args) { System.exit(SpringApplication.exit(SpringApplication.run( BatchConfiguration.class, args))); } }
你肯定会好奇,为啥Job就执行了呢?没看到调用啊
实际上在Spring batch的配置程序org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration里有以下代码
@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; }
也就是当配置文件里定义spring.batch.job.enabled为true,或者没定义(默认为true)的时候,会初始化一个JobLauncherCommandLineRunner的bean。
而在SpringApplication里有以下代码
private void callRunners(ApplicationContext context, ApplicationArguments args) { List
也就是只要能找到ApplicationRunner或者CommandLineRunner的子类,就挨个执行。
默认是没有ApplicationRunner的子类的,而CommandLineRunner得子类就是JobLauncherCommandLineRunner了,所以会执行所配置的job。
如果想自己执行job的话,使用以下代码便可。
@Autowired private JobLauncher jobLauncher; @Autowired private Job job; @Scheduled(initialDelay=3000,fixedRate = 1000) public void run(){ try { JobExecution execution = jobLauncher.run(job, new JobParameters()); System.out.println("Execution status: "+ execution.getStatus()); } catch (JobExecutionAlreadyRunningException | JobRestartException | JobInstanceAlreadyCompleteException | JobParametersInvalidException e) { e.printStackTrace(); } }
这时候,你可能会好奇,JobLauncher是哪儿配置的?
上面的配置文件里使用了注解@EnableBatchProcessing
这个注解会初始化以下所有bean
写道
JobRepository bean 名称 "jobRepository"
JobLauncher bean名称"jobLauncher"
JobRegistry bean名称"jobRegistry"
PlatformTransactionManager bean名称 "transactionManager"
JobBuilderFactory bean名称"jobBuilders"
StepBuilderFactory bean名称"stepBuilders"
JobLauncher bean名称"jobLauncher"
JobRegistry bean名称"jobRegistry"
PlatformTransactionManager bean名称 "transactionManager"
JobBuilderFactory bean名称"jobBuilders"
StepBuilderFactory bean名称"stepBuilders"
在程序org.springframework.batch.core.configuration.annotation.BatchConfigurationSelector会根据定义选择配置程序,默认用的是SimpleBatchConfiguration
public class BatchConfigurationSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { Class> annotationType = EnableBatchProcessing.class; AnnotationAttributes attributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes( annotationType.getName(), false)); Assert.notNull(attributes, String.format("@%s is not present on importing class '%s' as expected", annotationType.getSimpleName(), importingClassMetadata.getClassName())); String[] imports; if (attributes.containsKey("modular") && attributes.getBoolean("modular")) { imports = new String[] { ModularBatchConfiguration.class.getName() }; } else { imports = new String[] { SimpleBatchConfiguration.class.getName() }; } return imports; } }