欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring batch的自动运行

程序员文章站 2022-06-14 18:57:23
...

一个最简单的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<Object> runners = new ArrayList<Object>();
		runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
		runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
		AnnotationAwareOrderComparator.sort(runners);
		for (Object runner : new LinkedHashSet<Object>(runners)) {
			if (runner instanceof ApplicationRunner) {
				callRunner((ApplicationRunner) runner, args);
			}
			if (runner instanceof CommandLineRunner) {
				callRunner((CommandLineRunner) runner, args);
			}
		}
	}

 也就是只要能找到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"

 在程序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;
	}

}

 

相关标签: Spring batch Job