一个最简单的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;
}
}